分析无主键表再做优化

背景

新接手一项目,需要优化表,首先表中存在一些无主键的表,不确认是否用到了自增id做主键。
需求:
1.把id是主键的表字段存一文件中 这部分表不需要改动,只是记录就好,但如果只是id为主键但不bigint的后续也需要改。
2.把存在主键 但不是id的表字段单独存在一文件中,后续需要做优化。
3.没有主键的也存在一文件中,这部分优先处理。

思路:
首先想到的是information_schema.tables 和 columns关联 可以查出第一列信息(一般主键id都放在第一列 也存在例外)第一步先把表中的第一列取出 判断是否为主键,并记录信息 其它情况分别处理。

import pymysql

FIRST_COL_SQL = "select t.table_name,c.column_name,c.data_type,c.COLUMN_TYPE,c.column_key from  information_schema.tables t join information_schema.columns c  on t.table_name=c.table_name where t.table_schema ='db_name' and t.table_type like '%table%' and ORDINAL_POSITION=1 order by table_name"
FULL_COL_SQL  = "select table_name,column_name,data_type,COLUMN_TYPE,column_key from information_schema.columns where table_schema ='db_name' and table_name ='{}' order by table_name,column_name "

def processColInfo(hostname,uname,pword,db_name):
  #find first column of table  id common  if not id then use full_col_sql search exists id column 
  #exists then check if primary key or add primary key
  #                       0                                1                     2           3                4
  #first column res  | table_name                    | column_name         | data_type | COLUMN_TYPE    | column_key |
  justrecord = "/root/pyscript/justrecord.txt"
  fcr = executeSql(hostname,uname,pword,db_name,FIRST_COL_SQL)
  for lfcr in fcr:
    if lfcr[1].strip().lower().startswith('id'):
      if lfcr[4].strip().lower() == 'pri':
        # id is primary key write file of no_change 
        jrecord = "{:50} primary key is {:10}  type is {:30}\n".format(lfcr[0],lfcr[1],lfcr[3])
        writeFile(jrecord,justrecord)
      else:
        #second times check if has pri   
        processColNoPri(hostname,uname,pword,db_name,lfcr[0],True)
    # no id column then check if has pri  
    else: 
      processColNoPri(hostname,uname,pword,db_name,lfcr[0],False)

针对表中第一列不是id的表,查询其字段,并确认是否存在主键,有或没有分别记录。

def processColNoPri(hostname,uname,pword,db_name,table_name,firstcol_id):
  hasprimarykey = "/root/pyscript/hasprimary.txt"
  hasprimarykeynoid = "/root/pyscript/hasprimarynotid.txt"
  nopritable = "/root/pyscript/noprimary.txt"
  # table column res 
  print(table_name)
  fullcolsql = FULL_COL_SQL.format(table_name)
  tcr = executeSql(hostname,uname,pword,db_name,fullcolsql)
  loopcnt = 0

  while loopcnt < len(tcr):
    #print(table_name)
    #check table if has id column
    if not firstcol_id:
      if tcr[loopcnt][0].strip().lower().startswith('id'):
        firstcol_id = True
    #has pri 
    if tcr[loopcnt][0] is not None and tcr[loopcnt][0].strip() != "" and tcr[loopcnt][4].strip().lower() == 'pri':
      if firstcol_id:
        sqlstr = "###table {} primary key  {}  datatype {}\n".format(tcr[loopcnt][0],tcr[loopcnt][1],tcr[loopcnt][3])
        writeFile(sqlstr,hasprimarykey)
      else:
        sqlstr = "$$$table {} primary key  {}  datatype {} \n".format(tcr[loopcnt][0],tcr[loopcnt][1],tcr[loopcnt][3])
        writeFile(sqlstr,hasprimarykeynoid)
      break; 
    loopcnt +=1
  else:
  #no primary key
    nopri = "{} no id and no primary key \n".format(tcr[0][0])
    writeFile(nopri,nopritable)

连接数据库执行sql

#execute from mysql
def executeSql(hostname,uname,pword,db_name,sql):

  conn = pymysql.connect(host=hostname, port=31108, user=uname, password=pword)
  cursor = conn.cursor()
  changedb = 'use `{}`'.format(db_name)
  cursor.execute( changedb )

  #selsql

  cursor.execute(sql)
  res=[]
  try:
    res = cursor.fetchall()
  except pymysql.Error as err:
    print(err)
  finally:
    cursor.close()
    conn.close()
  return res

记录log

#write column info  to file 
def writeFile(info,filename='/root/col_log'):
  with open(filename,'a+') as f:
    f.write(info) 
if __name__ == '__main__':
  host = 'ip'
  user = 'user'
  pword = 'pass'
  db_name = 'dbname'
  processColInfo(host,user,pword,db_name)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你遇到的问题可能是由于索引和主键排序的不正确使用引起的。在MySQL的InnoDB引擎中,索引可以帮助提高查询效率,但是如果不正确使用索引或者主键排序,可能会导致性能下降。 首先,确保你的where字段有正确的索引。使用EXPLAIN语句来分析查询计划,看看是否使用了正确的索引。如果没有使用索引,可以考虑创建适当的索引来优化查询。 其次,注意主键排序的影响。InnoDB表的主键默认是聚集索引,意味着数据按照主键值的顺序进行物理存储。如果你在查询中使用了ORDER BY子句,并且排序的字段不是主键或者没有合适的索引,那么会导致全表扫描和排序操作,从而影响性能。 如果主键排序的性能问题仍然存在,可以考虑以下几点优化方案: 1. 考虑修改表结构,更改主键或者添加合适的索引来优化排序操作。 2. 使用覆盖索引,即创建一个包含所有需要查询的字段的索引。这样就可以避免回表操作,提高查询效率。 3. 考虑使用缓存技术,如使用Redis等缓存热门数据,减少数据库查询的频率。 4. 考虑分库分表,将数据拆分到多个表或者数据库中,减少单个表的数据量,提高查询效率。 总之,在处理MySQL的InnoDB引擎中的索引和排序性能问题时,需要综合考虑索引的使用、主键排序和表结构等方面的因素,以找到最佳的优化方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值