欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python如何識(shí)別 MySQL 中的冗余索引

 更新時(shí)間:2022年10月18日 09:01:13   作者:Bing@DBA  
冗余索引也是一個(gè)非常重要的巡檢目,表中索引過多,會(huì)導(dǎo)致表空間占用較大,索引的數(shù)量與表的寫入速度與索引數(shù)成線性關(guān)系(微秒級(jí)),如果發(fā)現(xiàn)有冗余索引,建議立即審核刪除,這篇文章主要介紹了Python 識(shí)別 MySQL 中的冗余索引,需要的朋友可以參考下

前言

最近在搞標(biāo)準(zhǔn)化巡檢平臺(tái),通過 MySQL 的元數(shù)據(jù)分析一些潛在的問題。冗余索引也是一個(gè)非常重要的巡檢目,表中索引過多,會(huì)導(dǎo)致表空間占用較大,索引的數(shù)量與表的寫入速度與索引數(shù)成線性關(guān)系(微秒級(jí)),如果發(fā)現(xiàn)有冗余索引,建議立即審核刪除。

PS:之前見過一個(gè)客戶的數(shù)據(jù)庫上面竟然創(chuàng)建 300 多個(gè)索引???當(dāng)時(shí)的想法是 “他們?cè)谕媾帕薪M合呢” 表寫入非常慢,嚴(yán)重影響性能和表維護(hù)的復(fù)雜度。

腳本介紹

表結(jié)構(gòu)

下方是演示的表結(jié)構(gòu):

CREATE TABLE `index_test03` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `create_time` varchar(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uqi_name` (`name`),
  KEY `idx_name` (`name`),
  KEY `idx_name_createtime`(name, create_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

MySQL 元數(shù)據(jù)

MySQL 可以通過 information_schema.STATISTICS 表查詢索引信息:

SELECT * from information_schema.STATISTICS  where TABLE_SCHEMA = 'test02' and TABLE_NAME = 'index_test03';
TABLE_CATALOGTABLE_SCHEMATABLE_NAMENON_UNIQUEINDEX_SCHEMAINDEX_NAMESEQ_IN_INDEXCOLUMN_NAMECOLLATIONCARDINALITYSUB_PARTPACKEDNULLABLEINDEX_TYPECOMMENTINDEX_COMMENT
deftest02index_test030test02PRIMARY1idA0NULLNULL BTREE  
deftest02index_test030test02uqi_name1nameA0NULLNULL BTREE  
deftest02index_test031test02idx_name1nameA0NULLNULL BTREE  
deftest02index_test031test02idx_name_createtime1nameA0NULLNULL BTREE  
deftest02index_test031test02idx_name_createtime2create_timeA0NULLNULL BTREE  

腳本通過獲得 STATISTICS 表中的索引信息來分析表中是否存在冗余索引,分析粒度為表級(jí)別。

DEMO 演示

需要使用 pandas 模塊。

import pandas as pd

df_table_level = pd.read_excel('/Users/cooh/Desktop/STATISTICS.xlsx')

table_indexes = df_table_level['INDEX_NAME'].drop_duplicates().tolist()

_indexes = list()
for index_name in table_indexes:
    index_info = {'index_cols': df_table_level[df_table_level['INDEX_NAME'] == index_name]['COLUMN_NAME'].tolist(),
                  'non_unique': df_table_level[df_table_level['INDEX_NAME'] == index_name]['NON_UNIQUE'].tolist()[0],
                  'index_name': index_name
                  }
    _indexes.append(index_info)

content = ''
election_dict = {i['index_name']: 0 for i in _indexes}

while len(_indexes) > 0:
    choice_index_1 = _indexes.pop(0)

    for choice_index_2 in _indexes:
        # 對(duì)比兩個(gè)索引字段的個(gè)數(shù),使用字段小的進(jìn)行迭代
        min_len = min([len(choice_index_1['index_cols']), len(choice_index_2['index_cols'])])

        # 獲得相似字段的個(gè)數(shù)據(jù)
        similarity_col = 0
        for i in range(min_len):
            # print(i)
            if choice_index_1['index_cols'][i] == choice_index_2['index_cols'][i]:
                similarity_col += 1

        # 然后進(jìn)行邏輯判斷
        if similarity_col == 0:
            # print('毫無冗余')
            pass
        else:
            # 兩個(gè)索引的字段包含內(nèi)容都相同,說明兩個(gè)索引完全相同,接下來就需要從中選擇一個(gè)刪除
            if len(choice_index_1['index_cols']) == similarity_col and len(
                    choice_index_2['index_cols']) == similarity_col:
                # 等于 0 表示有唯一約束
                if choice_index_1['non_unique'] == 1:
                    content += '索引 {0} 與索引 {1} 重復(fù), '.format(choice_index_2['index_name'], choice_index_1['index_name'])
                    election_dict[choice_index_1['index_name']] += 1
                elif choice_index_2['non_unique'] == 1:
                    content += '索引 {0} 與索引 {1} 重復(fù), '.format(choice_index_1['index_name'], choice_index_2['index_name'])
                    election_dict[choice_index_2['index_name']] += 1
                else:
                    content += '索引 {0} 與索引 {1} 重復(fù), '.format(choice_index_2['index_name'], choice_index_1['index_name'])
                    election_dict[choice_index_1['index_name']] += 1

            elif len(choice_index_1['index_cols']) == similarity_col and choice_index_1['non_unique'] != 0:
                content += '索引 {0} 與索引 {1} 重復(fù), '.format(choice_index_2['index_name'], choice_index_1['index_name'])
                election_dict[choice_index_1['index_name']] += 1

            elif len(choice_index_2['index_cols']) == similarity_col and choice_index_1['non_unique'] != 0:
                content += '索引 {0} 與索引 {1} 重復(fù), '.format(choice_index_1['index_name'], choice_index_2['index_name'])
                election_dict[choice_index_2['index_name']] += 1

redundancy_indexes = list()
for _k_name, _vote in election_dict.items():
    if _vote > 0:
        redundancy_indexes.append(_k_name)

content += '建議刪除索引:{0}'.format(', '.join(redundancy_indexes))

print(content)

輸出結(jié)果:

索引 uqi_name 與索引 idx_name 重復(fù), 索引 idx_name_createtime 與索引 idx_name 重復(fù), 建議刪除索引:idx_name

SQL 查詢?nèi)哂嗨饕?/h2>

MySQL 5.7 是可以直接通過 sys 元數(shù)據(jù)庫中的視圖來查冗余索引的,但是云上 RDS 用戶看不到 sys 庫。所以才被迫寫這個(gè)腳本,因?yàn)閷?shí)例太多了,一個(gè)一個(gè)看不現(xiàn)實(shí)。如果你是自建的 MySQL,就不用費(fèi)那么大勁了,直接使用下面 SQL 來統(tǒng)計(jì)。

select * from sys.schema_redundant_indexes;

后記

刪除索引屬于高危操作,刪除前需要多次 check 后再刪除。上面是一個(gè) demo 可以包裝成函數(shù),使用 pandas 以表為粒度傳入數(shù)據(jù),就可以嵌入到程序中。有問題歡迎評(píng)論溝通。

到此這篇關(guān)于Python 識(shí)別 MySQL 中的冗余索引的文章就介紹到這了,更多相關(guān)MySQL冗余索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用socket的UDP協(xié)議實(shí)現(xiàn)FTP文件服務(wù)功能

    Python使用socket的UDP協(xié)議實(shí)現(xiàn)FTP文件服務(wù)功能

    這篇文章主要介紹了Python使用socket的UDP協(xié)議實(shí)現(xiàn)FTP文件服務(wù),本示例主要是用Python的socket,使用UDP協(xié)議實(shí)現(xiàn)一個(gè)FTP服務(wù)端、FTP客戶端,用來實(shí)現(xiàn)文件的傳輸,需要的朋友可以參考下
    2023-10-10
  • 解決python3輸入的坑——input()

    解決python3輸入的坑——input()

    這篇文章主要介紹了解決python3輸入的坑——input(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 教你使用Python獲取QQ音樂某個(gè)歌手的歌單

    教你使用Python獲取QQ音樂某個(gè)歌手的歌單

    這篇文章主要介紹了Python獲取QQ音樂某個(gè)歌手的歌單,從qq音樂中獲取某個(gè)你喜歡的歌手的清單,涉及到的庫有requests、json,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • python如何利用plt.legend()添加圖例代碼示例

    python如何利用plt.legend()添加圖例代碼示例

    用python的matplotlib畫圖時(shí),往往需要加圖例說明,下面這篇文章主要給大家介紹了關(guān)于python如何利用plt.legend()添加圖例的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • python利用socket實(shí)現(xiàn)客戶端和服務(wù)端之間進(jìn)行通信

    python利用socket實(shí)現(xiàn)客戶端和服務(wù)端之間進(jìn)行通信

    這篇文章主要介紹了python實(shí)現(xiàn)客戶端和服務(wù)端之間進(jìn)行通信,文章通過python利用socket展開詳情介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • 一文詳解PyQt5中實(shí)現(xiàn)不規(guī)則窗口的顯示

    一文詳解PyQt5中實(shí)現(xiàn)不規(guī)則窗口的顯示

    這篇文章主要為大家詳細(xì)介紹了Python?PyQt5中實(shí)現(xiàn)不規(guī)則窗口的顯示的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-12-12
  • python淺析守護(hù)線程與非守護(hù)線程的區(qū)別與使用

    python淺析守護(hù)線程與非守護(hù)線程的區(qū)別與使用

    守護(hù)線程,又稱后臺(tái)線程,它是在后臺(tái)運(yùn)行的,如果所有前臺(tái)線程都死亡,那么后臺(tái)線程就會(huì)自動(dòng)死亡,本章我們來了解守護(hù)線程與非守護(hù)線程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-08-08
  • IDLE下Python文件編輯和運(yùn)行操作

    IDLE下Python文件編輯和運(yùn)行操作

    這篇文章主要介紹了IDLE下Python文件編輯和運(yùn)行操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python的線程之線程同步

    Python的線程之線程同步

    這篇文章主要為大家介紹了Python線程同步,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • django 數(shù)據(jù)庫 get_or_create函數(shù)返回值是tuple的問題

    django 數(shù)據(jù)庫 get_or_create函數(shù)返回值是tuple的問題

    這篇文章主要介紹了django 數(shù)據(jù)庫 get_or_create函數(shù)返回值是tuple的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05

最新評(píng)論