2016-10-18 32 views
2

大きなテーブルに小さな参加私は、次の表を持っている:のMySQL:パフォーマンスの低下が

CREATE TABLE smalltable (
    smalltable_id VARCHAR(64) NOT NULL, 
    bigtable_id VARCHAR(64), 
    ... 
    PRIMARY KEY (smalltable_id) 
) ENGINE=InnoDB; 

CREATE TABLE bigtable (
    bigtable_id VARCHAR(64) NOT NULL, 
    count BIGINT, 
    PRIMARY KEY (bigtable_id) 
) ENGINE=InnoDB; 

smalltableさは約8000行とbigtable約40万ドルを持っています。私はこれらの行をsmalltableから検索したいと思います。smalltable.bigtable_idbigtableにあります。次のクエリが完了するまでに約10時間かかりました。ここで

SELECT * FROM smalltable 
INNER JOIN bigtable 
ON smalltable.bigtable_id = bigtable.bigtable_id; 

EXPLAINの出力です:

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: smalltable 
    partitions: NULL 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 8610 
    filtered: 100.00 
     Extra: NULL 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: bigtable 
    partitions: NULL 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 38818260 
    filtered: 100.00 
     Extra: Using where; Using join buffer (Block Nested Loop) 

私はこれを解釈するには専門家だが、MySQLは、シーケンシャルスキャンを行っているように見えます両方のテーブルでsmalltableのすべての行を繰り返し実行し、smalltableの各行に対してbigtableSELECTクエリを実行する小さなPythonスクリプトを作成すると、すべてが25秒で終了します。私は単一のSQLクエリで同じ種類のパフォーマンスを持っていたいと思います。

+1

はsmalltable(bigtable_id)にインデックスを追加し、(あなたの説明が意味するものである)smalltableからの情報が必要な場合は – Strawberry

+0

感謝。それは実際に物事をかなりスピードアップさせます。クエリには現在1分30秒かかります。ただし、手動でsmalltableを繰り返し実行し、selectクエリをbigtableに送り出すよりも遅いです。また、小さなテーブルの変更を必要としないソリューションがあればうれしいでしょう。実際の使用事例では、smalltableのデータは別の大きなテーブルのサブセットであり、そのテーブルに対する書き込み権限はありません。 –

+1

インデックスはどこにあるのですか?代わりに、あなたがしていることをやることです。 – Strawberry

答えて

0

メイン・ソースである表がオプティマイザ・パスであるかどうかを確認してください。スローな場合は、bigtableが主ソースとして使用されます。この方法を試してください。

SELECT STRAIGHT_JOIN * FROM smalltable 
INNER JOIN bigtable 
ON smalltable.bigtable_id = bigtable.bigtable_id; 

STRAIGHT_JOINは、クエリでテーブルの順序に従うことをmysqlのを教えてくれます使用します。

0

あなただけ

SELECT * 
    FROM smalltable AS s 
    WHERE EXISTS (
     SELECT * 
      FROM bigtable 
      WHERE bigtable_id = s.bigtable_id); 
関連する問題