sql >> データベース >  >> RDS >> Mysql

インデックスを使用しないJOINを使用するMySQL

    以前のインストールと現在のインストールで見られる違いはわかりませんが、サーバーの動作は理にかなっています。

    SELECT  test_events.create_time  FROM  test_events  LEFT JOIN  test_event_types ON (  test_events.event =  test_event_types.id )  ORDER BY  test_events.create_time DESC LIMIT 1; 
    

    このクエリにはwhere句はありませんが、1行のみをフェッチしています。そして、それはcreate_timeで並べ替えた後です たまたまインデックスがあります。そして、そのインデックスは並べ替えに使用できます。しかし、2番目のクエリを見てみましょう。

    SELECT  test_events.create_time  FROM  test_events  LEFT JOIN  test_event_types ON (  test_events.event =  test_event_types.id ) WHERE base = 314 ORDER BY  test_events.create_time DESC LIMIT 1
    

    ベース列にインデックスがありません。したがって、その上でインデックスを使用することはできません。関連するレコードを見つけるために、mysqlはテーブルスキャンを実行する必要があります。関連する行を特定したら、それらを並べ替える必要があります。ただし、この場合、クエリプランナーは、create_timeでインデックスを使用するだけの価値はないと判断しました。

    セットアップにいくつかの問題があります。最初の問題は、baseにインデックスがないことです。 すでに述べたように。しかし、なぜベースvarcharなのですか?整数を格納しているようです。

    ALTER TABLE test_events
      ADD PRIMARY KEY (id),
      ADD KEY client (client),
      ADD KEY event_time (event_time),
      ADD KEY manager (manager),
      ADD KEY base_id (base_id),
      ADD KEY create_time (create_time);
    

    そして、このように複数のインデックスを作成することは、mysqlではあまり意味がありません。これは、mysqlがクエリにテーブルごとに1つのインデックスしか使用できないためです。 1つまたは2つのインデックスを使用する方がはるかに良いでしょう。おそらく複数列のインデックス。

    理想的なインデックスには、create_timeフィールドとeventフィールドの両方が含まれると思います



    1. 1つのスポットでSQLCTEについて知っておくべきことすべて

    2. Oracle構文エラー

    3. SQLJOIN多対多

    4. 春のデータを使用した日付ASCによる注文