1. 程式人生 > >python 統計MySQL大於100萬的表

python 統計MySQL大於100萬的表

一、需求分析

線上的MySQL伺服器,最近有很多慢查詢。需要統計出行數大於100萬的表,進行統一優化。

需要篩選出符合條件的表,統計到excel中,格式如下:

庫名 表名 行數
db1 users 1234567

 

 

 

二、統計表的行數

統計表的行數,有2中方法:

1. 通過查詢mysql的information_schema資料庫中INFODB_SYS_TABLESTATS表,它記錄了innodb型別每個表大致的資料行數

2. select count(1) from 庫名.表名 

 

下面來分析一下這2種方案。

第一種方案,不是精確記錄的。雖然效率快,但是表會有遺漏!

第二鍾方案,才是準確的。雖然慢,但是表不會遺漏。

 

備註:

count(1)其實這個1,並不是表示第一個欄位,而是表示一個固定值。

count(1),其實就是計算一共有多少符合條件的行。
1並不是表示第一個欄位,而是表示一個固定值。
其實就可以想成表中有這麼一個欄位,這個欄位就是固定值1,count(1),就是計算一共有多少個1.

 

寫入json檔案

下面這段程式碼,是參考我之前寫的一篇文章:

https://www.cnblogs.com/xiao987334176/p/9901692.html

 

在此基礎上,做了部分修改,完整程式碼如下:

#!/usr/bin/env python3
# coding: utf-8

import pymysql
import json

conn = pymysql.connect(
    host="192.168.91.128",  # mysql ip地址
    user="root",
    passwd="root",
    port=3306,  # mysql 埠號,注意:必須是int型別
    connect_timeout = 3  # 超時時間
)

cur 
= conn.cursor() # 建立遊標 # 獲取mysql中所有資料庫 cur.execute('SHOW DATABASES') data_all = cur.fetchall() # 獲取執行的返回結果 # print(data_all) dic = {} # 大字典,第一層 for i in data_all: if i[0] not in dic: # 判斷庫名不在dic中時 # 排序列表,排除mysql自帶的資料庫 exclude_list = ["sys", "information_schema", "mysql", "performance_schema"] if i[0] not in exclude_list: # 判斷不在列表中時 # 寫入第二層資料 dic[i[0]] = {'name': i[0], 'table_list': []} conn.select_db(i[0]) # 切換到指定的庫中 cur.execute('SHOW TABLES') # 檢視庫中所有的表 ret = cur.fetchall() # 獲取執行結果 for j in ret: # 查詢表的行數 cur.execute('select count(1) from `%s`;'% j[0]) ret = cur.fetchall() # print(ret) for k in ret: print({'tname': j[0], 'rows': k[0]}) dic[i[0]]['table_list'].append({'tname': j[0], 'rows': k[0]}) with open('tj.json','w',encoding='utf-8') as f: f.write(json.dumps(dic))
View Code

 

三、寫入excel中

直接讀取tj.json檔案,進行寫入,完整程式碼如下:

#!/usr/bin/env python3
# coding: utf-8

import xlwt
import json
from collections import OrderedDict

f = xlwt.Workbook()
sheet1 = f.add_sheet('統計', cell_overwrite_ok=True)
row0 = ["庫名", "表名", "行數"]

# 寫第一行
for i in range(0, len(row0)):
    sheet1.write(0, i, row0[i])

# 載入json檔案
with open("tj.json", 'r') as load_f:
    load_dict = json.load(load_f)  # 反序列化檔案
    order_dic = OrderedDict()  # 有序字典
    for key in sorted(load_dict):  # 先對普通字典key做排序
        order_dic[key] = load_dict[key]  # 再寫入key

    num = 0  # 計數器
    for i in order_dic:

        # 遍歷所有表
        for j in order_dic[i]["table_list"]:
            # 判斷行數大於100萬時
            if j['rows'] > 1000000:
                # 寫入庫名
                sheet1.write(num + 1, 0, i)
                # 寫入表名
                sheet1.write(num + 1, 1, j['tname'])
                # 寫入行數
                sheet1.write(num + 1, 2, j['rows'])
                num += 1  # 自增1

    f.save('test1.xls')
View Code

 

執行程式,開啟excel檔案,效果如下: