2016-06-17 3 views
2

MySQL(InnoDB)でインデックスの設定が正しいかどうか疑問に思っています。私はインデックスの専門家ではなく、私がそれらについて読んだものからです希望私はよく理解しました。私が正しいことを確認するために、私はこのコミュニティのメンバーに尋ねたいと思います。フィールドidのID、フルネーム、地位、性別、...MySQLは私のインデックスが良いですか?

2) "受注"、:

1) "ユーザー"、フィールドを持つ:

は、私は2つのテーブルを持っています、id_user、order_date

私が注文を見つけると、私は "id_user"から "users"(id)にリンクします。

約1mioのユーザーがおり、「注文」の「ステータス」フィールドには10種類の異なる値を設定できます。

プライマリインデックス

私はフィールド "ユーザー:ID" のPRIMARYインデックス持って、私はINDEX(PRIMARY)を使用して、ユーザーから選択」のようなクエリを実行するときに便利であると考えている(ID = 33 ) "と私は特定のユーザーに注文をリンクします。私がテーブル「注文」に持っている同様のインデックス。これはおそらく大丈夫です。

問題

私はその状態で注文を検索し、ユーザーを修正するためにそれをリンクしますので、私はテーブル「受注」に二つのフィールドにインデックスを作成しました:

インデックス名「status__id_user」 、フィールド(ステータス、id_user)

新規受注の一覧を表示し、適切なユーザーとリンクする私のクエリは次のようになります。

SELECT *注文がINDEX(status__id_user)を使用することから、ユーザーは(PRIMARY)WHERE(ORDERS.STATUS = '新しい')AND(orders.id_user = users.id)

質問

ドインデックスを使用しますフィールド "id_user"を持つユーザテーブルにリンクしているため、2つのフィールドにインデックスが必要ですか? "orders"テーブルの私のインデックスがフィールド "status"だけのものであれば、それはスピードアップしますか?その場合、100,000レコードが選択され、MySQLはそれを「users」テーブルにリンクして正しいユーザーを取得します。

私のインデックスは、クエリのこの部分をスピードアップするためにとにかく場合に役立ちます私の質問は次のとおりです。

AND(orders.id_user = users.id)

ありがとうございました!

+2

基本的な経験則:「決定」コンテキストで使用されるフィールドには、インデックスが必要です。 'where'、' join'、 'order by'などで使われるものです。 –

+0

初期フィールドリストは、' status'フィールドを 'user'テーブルに置きます。それは間違っていると思いますか? –

+0

**インデックスを使用するオプティマイザは決して**とは言いません。あなたは失う。オプティマイザが優れています。オプティマイザが最適なインデックスを取得するようにクエリを変更します。 EXPLAIN SELECTで問合せを選択してください –

答えて

2

は、クエリをこのように書く:

SELECT * 
    FROM orders 
    JOIN users ON orders.id_user = users.id 
    WHERE orders.status='new' 

インデックスが使用するものを指定しないでください。

WHERE句からは、かもしれません。が役に立ちます:INDEX(status)。しかし、 "状態"はカーディナリティの低い "フラグ"のように聞こえるので、オプティマイザにインデックスを無視し、単にテーブルスキャンを行うことにします。 これは問題ありません。インデックスがあまり選択的でない場合、インデックスとデータの間のバウンスよりもテーブルスキャンを行うほうが速いので問題ありません。いずれにせよ、決定をオプティマイザに任せてください。

ordersを扱ったので、JOINusersにする必要があります。これを行う唯一の方法は、idにインデックスを付けることです。その名前(「id」)は、それがPRIMARY KEYかもしれないことを意味しますか? (SHOW CREATE TABLEを提供してください。)

Index cookbook

あなたが言及した他のクエリでは、すでに述べたように、id上のインデックスは(PRIMARY KEY?)正しいことで、

SELECT * FROM users WHERE id=33 

を書かれてしなければなりません。

INDEX(status, id_user)の場合、少なくとも(与えられたSELECTsに対して)利点はありません。選択にはすべての列(*)が含まれています。 id_userしか取得していない場合、そのようなインデックスは「カバー」され、いくつかの利点があります。

関連する問題