2

データベースのインデックスを最適化する手順を作成していますが、時間がかかります。それで、それが実行可能かどうかを確認したいですか?そして、他の方法でそれを取得したいのはまだ行われていません。

  1. すべてのテーブルからすべてのインデックスを読み取りたい。
  2. 主キーであるフィールドに他のすべてのインデックスを削除したい
  3. 上記を行った後。まだ一意としてインデックス付けされているフィールド。他のすべてのインデックスを削除したい
  4. プライマリでも一意でもないフィールド。それぞれに1つのインデックスのみを保持し、他のすべてのインデックスを削除したい

なぜMYSQLが主キーフィールドに一意のインデックスを許可するのか興味がありますか?それは何か有用な違いを生むことができますか?

質問:上記の4つのポイントで述べた階層を持つすべての役に立たないインデックスを削除するには、ガイダンス/クエリ/手順が必要です

更新1:SQLFiddleで作業を更新し続けます。現時点ではまだ始まったばかりです。ただし、このリンクでは、4つのフィールドと8つのインデックスがあることがわかります。そのうちの3つだけが必要で、他はすべて削除します。必要なのは1番目、3番目、4番目だけです。私の上記の4つのポイントによると。

アップデート2:eggayalから素晴らしい回答を得ました。彼が与えた最初のリンクは純粋なSQLソリューションです。Link2で試してみました。それは私に望ましくない出力を与えました。link2の出力は、ここでLink1を調べることで比較できます。

必要な出力は

    COLUMN_NAMES REDUNDANT_INDEXES
1 auth_id `auth_id_3`、` auth_id_2`、 `auth_id`
2 id `id_2`、` id_3`
3件名`subject_1`

Link2のクエリの出力の障害

auth_id_4Row1:auth_idは、同じフィールドの一意のキーとは何の関係もない(比較する)ため、冗長インデックスとして表示されません。ただし、同じ列に一意のインデックスがある場合はこのインデックスは必要ないため、必要です。

行2:一部の列に主キーインデックスが存在する場合、他のすべてのインデックスは冗長であると言いたい

3列目:大丈夫です

4

3 に答える 3

2

私はc#でアプリケーションを作成しました。それはあなたの優先順位に従って重複したインデックスを削除します、それが役立つことを願っています

多くの改善が必要かもしれませんが、私が知っているのは...プライマリ(複合)と外部キーに同時に関与する重複インデックスだけを削除するわけではありません(通常は良いアプローチではないはずです)

ソース付きの完全なアプリケーションのダウンロードリンクは次のとおりです

上記リンクのメインファイルは以下のとおりです

using System;
using System.Data;
using MySql.Data.MySqlClient;
using System.Collections.Generic;

namespace duplicateIndexRemover
{
public class duplicateIndexRemover
{

    static List<string> toDrop;
    public string main(System.Windows.Forms.DataGridView dgv, System.Windows.Forms.DataGridView dgv1, string dbName)
    {            
        try
        {
            toDrop = new List<string>();
            List<table> tbs = new List<table>();
            DataTable dt1 = new DataTable();
            string cnStr = "SERVER=localhost;DATABASE=" + dbName + ";UID=root;";
            MySqlConnection conn = new MySqlConnection(cnStr);
            MySqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = @"SELECT Table_Name,Column_Name,Index_Name,NON_UNIQUE
            FROM information_schema.STATISTICS
            WHERE table_schema = '" + dbName + "' order by Table_Name,Column_Name,Index_Name";
            MySqlDataAdapter adp = new MySqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            adp.Fill(dt);
            dgv.DataSource = dt;
            for (int i = 0; i < dt.Columns.Count - 1; i++)
                dt1.Columns.Add(dt.Columns[i].ColumnName);

            table tb = new table();
            column cl = new column();
            index dx = new index();
            tb.nam = dt.Rows[0][0].ToString();
            cl = addColumn(dt, tb, 0);
            tbs.Add(tb);

            for (int i = 1; i < dt.Rows.Count; i++)
            {
                if (tb.nam != dt.Rows[i][0].ToString())
                {
                    // 1st column of (current) t_th table
                    tb = new table();
                    tb.nam = dt.Rows[i][0].ToString();
                    cl = addColumn(dt, tb, i);
                    tbs.Add(tb);
                }
                else
                {
                    if (cl.nam != dt.Rows[i][1].ToString())
                        cl = addColumn(dt, tb, i);
                    else
                    {

                        // Duplicate Indices
                        // But this one may be primary/unique key
                        // Then it would not be good to make a drop statement for this index here
                        // It may be improvable, but i can not apply as well condition here if it is not primary key
                        addIndex(dt, cl, i);
                    }
                }
            }
            makeDropStatements(tbs, dt1);

            dgv1.DataSource = dt1;
            cmd.Connection.Open();
            for (int i = 0; i < toDrop.Count; i++)
            {
                cmd.CommandText = toDrop[i];
                try
                {
                    cmd.ExecuteScalar();
                }
                catch//(Exception ex)
                {
                    //System.Windows.Forms.MessageBox.Show("Table : " + dt1.Rows[i][0] + " Column : " + dt1.Rows[i][1] + "\n\n" + ex.Message);
                }
            }

            cmd.CommandText = @"select table_name from information_schema.STATISTICS
            WHERE table_schema = '" + dbName + "' group by table_name,column_name";
            DataTable dg = new DataTable();
            adp.Fill(dg);

            string msg = " Total Number of Indices : " + dt.Rows.Count;
            msg += "\t Droppable Indices : " + toDrop.Count;
            msg += "\t Total Number of Indexed Columns : " + dg.Rows.Count;
            return msg;
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message);
            return ex.Message;
        }
    }

    private static column addColumn(DataTable dt, table tb, int i)
    {
        column cl = new column();
        // 1st index of i_th column of t_th table
        cl.nam = dt.Rows[i][1].ToString();
        addIndex(dt, cl, i);
        tb.cols.Add(cl);
        return cl;
    }

    private static void addIndex(DataTable dt, column cl, int i)
    {
        index dx = new index();
        dx.nam = dt.Rows[i][2].ToString();
        dx.non_unique = Convert.ToBoolean(dt.Rows[i][3]);
        cl.indices.Add(dx);
    }


    private static void makeDropStatements(List<table> tbs, DataTable dt1)
    {
        bool chekd;
        List<index> temp;
        for (int t = 0; t < tbs.Count; t++)
        {                
            for (int i = 0; i < tbs[t].cols.Count; i++)
            {                    
                temp = tbs[t].cols[i].indices;
                if (temp.Count > 1)
                {

                    chekd = false;
                    for (int j = 0; j < temp.Count; j++)
                    {
                        if (temp[j].nam == "PRIMARY")
                        {
                            getToDropIndices(tbs[t].nam, tbs[t].cols[i].nam, temp, j, dt1);
                            chekd = true;
                            break;
                        }
                    }
                    if (!chekd)
                    {
                        for (int j = 0; j < temp.Count; j++)
                        {
                            if (!temp[j].non_unique)
                            {
                                getToDropIndices(tbs[t].nam, tbs[t].cols[i].nam, temp, j, dt1);
                                chekd = true;
                                break;
                            }
                        }
                    }
                    if (!chekd)
                    {
                        getToDropIndices(tbs[t].nam, tbs[t].cols[i].nam, temp, 0, dt1);
                        chekd = true;
                        break;
                    }
                }
            }
        }
    }

    private static void getToDropIndices(string tbl, string col, List<index> sublist, int nt, DataTable dt1)
    {
        for (int j = 0; j < nt; j++)
        {
            toDrop.Add("alter table `" + tbl + "` drop index " + sublist[j].nam);
            dt1.Rows.Add(dt1.NewRow());
            int r = dt1.Rows.Count - 1;
            dt1.Rows[r][0] = tbl;
            dt1.Rows[r][1] = col;
            dt1.Rows[r][2] = sublist[j].nam;
        }
        for (int j = nt + 1; j < sublist.Count; j++)
        {
            toDrop.Add("alter table `" + tbl + "` drop index " + sublist[j].nam);
            dt1.Rows.Add(dt1.NewRow());
            int r = dt1.Rows.Count - 1;
            dt1.Rows[r][0] = tbl;
            dt1.Rows[r][1] = col;
            dt1.Rows[r][2] = sublist[j].nam;
        }
    }
}

public class table
{
    public List<column> cols =new List<column>();
    public string nam = "";
}

public class column
{
    public List<index> indices = new List<index>();
    public string nam = "";
}

public class index
{
    public string nam = "";
    public bool non_unique;
}
}

インデックスを表示するためだけのグリッドビューは無視/削除できます。main関数を呼び出すだけです

于 2012-10-30T12:53:13.127 に答える
2

Roland Boumanは、このテーマに関するブログ記事を書き、純粋なSQLソリューションを示しました。

グーグルでのクイック検索もまた激怒した:

于 2012-10-05T08:42:44.130 に答える
1

リンクに表示されている内容に基づくと、次のような無関係なインデックスがいくつかあるようです。

KEY `auth_id_2` (`auth_id`),
KEY `auth_id_4` (`auth_id`),
KEY `auth_id_5` (`auth_id`),
KEY `auth_id_6` (`auth_id`)

多分それらは異なった方法で作られていると思いました。たとえば、1つはBTREEで、もう1つはHASHである可能性があり、これは潜在的に何らかの目的に役立つ可能性があります。しかし、SHOWによれば、それらはすべて同じです。余分に同一のものを削除することは問題ではないはずです。

ただし、たとえば、これら3つすべてを使用することには目的があります。

KEY `articleid` (`artid`),
KEY `artSub` (`artSub`),
KEY `comments_ibfk_3` (`artSub`,`artid`)

2つの列にインデックスを作成することは、1つに2つの別々のインデックスを作成することと必ずしも同じではありません。

于 2012-10-05T08:21:29.107 に答える