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

Mysqlの遅いクエリ:JOIN+複数のWHERES+ ORDER BY

    インデックスはmysqlに大きな違いをもたらします。間違ったインデックスのセットで15分かかった1つのクエリは、正しいインデックスでは.2秒かかりましたが、一般的に問題となる適切なバランスを見つけることができます。当然のことながら、いくつかのサンプルデータがなければ、以下の解決策で時間を節約できるかどうかを判断するのは非常に困難ですが、理論的にはそうする必要があります。

    あなたの質問に答えるために、私は次のようにテーブルを再設計します:

    CREATE TABLE `product_all` ( 
    `prod_id` INT( 10 ) NOT NULL, 
    `ref_id` INT( 10) NOT NULL, 
    `date` DATE NOT NULL , 
    `buy_link` BLOB NOT NULL , 
    `sale_price` FLOAT NOT NULL,
    PRIMARY KEY (prod_id, ref_id) ,
    INDEX date_Index (`date` ASC),
    UNIQUE INDEX prod_price_Index (prod_id ASC, sale_price ASC)
    ) ENGINE = MYISAM ; 
    
    
    CREATE TABLE `product_info` ( 
    `prod_id` INT( 10 ) NOT NULL AUTO_INCREMENT, 
    `prod_name` VARCHAR( 200 ) NOT NULL, 
    `brand` VARCHAR( 50 ) NOT NULL, 
    `retail_price` FLOAT NOT NULL, 
    `category` INT( 3 ) NOT NULL, 
    `gender` VARCHAR( 1 ) NOT NULL, 
    `type` VARCHAR( 10 ) NOT NULL,
    PRIMARY KEY (prod_id) ,
    UNIQUE INDEX prod_id_name_Index (prod_id ASC, prod_name ASC),
    INDEX category_Index (category ASC),
    INDEX gender_Index (gender ASC)
    ) ENGINE = MYISAM ;
    
    SELECT product_info.*, MIN(product_all.sale_price) as sale_price, product_all.buy_link         
    FROM product_info         
    NATURAL JOIN (SELECT * FROM product_all WHERE product_all.date = '2010-09-30') as product_all         
    WHERE (product_info.category = 2           
    AND product_info.gender = 'W' )         
    GROUP BY product_all.prod_id         
    ORDER BY MIN(product_all.sale_price) ASC LIMIT 13        
    

    ここでのパフォーマンスの向上は、結合され、where句で取り上げられているメインフィールドのインデックスを作成することで得られます。個人的には、最初のクエリを使用して、パフォーマンスが向上するはずだと考えます。

    最初と2番目のクエリで何が起こっているかを理解している限り:

    • 最初のクエリは、自然結合を実行する前にサブクエリによってフィルタリングされます。つまり、テーブル全体ではなく、結果のデータにのみ結合されます。
    • 2番目のクエリは、2番目のテーブル全体を結合し、結果として得られたロット全体の行をフィルタリングして、必要なものに戻します。

    経験則として、通常、主要な結合フィールドと、where句で最もよく使用するフィールドにインデックスを追加する必要があります。また、prod_id_name_Indexなど、定期的にクエリするフィールドのいくつかに一意のインデックスをいくつか配置しました。

    これでパフォーマンスが向上しない場合は、ダミーデータを投稿して試してみることができれば、ベンチマークできるより高速なソリューションを入手できる可能性があります。

    こちら mysqlでのパフォーマンスのインデックス作成について説明している記事です。詳細を知りたい場合は、一読する価値があります。

    頑張ってください!

    編集:私が最初に見逃した最後の質問です。答えは、メインの結合フィールドのインデックスを作成した場合、全体的なパフォーマンスにわずかに影響するだけですが、テーブルに配置した一意のインデックスがクエリのベースにしたいものの大部分。覚えておくべき主なことは、フィールドに頻繁にクエリを実行したり結合したりする場合は、実際にインデックスを作成する必要がありますが、マイナーなクエリや順序の変更は、インデックス作成戦略の再調整に関して心配する必要はありません。



    1. 接続プールの問題

    2. 大規模なMySQLインポートの接続タイムアウトを防ぐ方法

    3. SQLSELECTでIF...THENを実行するにはどうすればよいですか?

    4. Hashsetを休止状態で永続化することはできません