1

私は良いMySQLクエリを作成するのがとても苦手です。私はこれを作成しました:

SELECT SQL_CALC_FOUND_ROWS
  `products_stock`.`products_id`,
  `products_stock`.`products_stock_attributes`,
  `products_stock`.`products_stock_quantity`,
  `products`.`manufacturers_id`,
  `products_description`.`products_name`
FROM `products_stock` 
  LEFT JOIN  `products`
    ON  `products_stock`.`products_id` = `products`.`products_id` 
  LEFT JOIN  `products_description`
    ON  `products_stock`.`products_id` = `products_description`.`products_id` 
  LEFT JOIN  `products_to_categories`
    ON `products_stock`.`products_id` = `products_to_categories`.`products_id` 
WHERE `products_stock`.`products_stock_quantity` >=3
  AND `products`.`products_status` = 1
  AND ISNULL(`products`.`products_image`) = false
  AND `products`.`products_image` != ""
  AND EXISTS(
   select * from `allegro`
   where `products_stock`.`products_id` = `allegro`.`product_id` 
     and `allegro`.`attributes` =  `products_stock`.`products_stock_attributes`
  ) = false

productsテーブルには約17k行、 allegroテーブルには約3k行があります。

クエリIdeaは、すべての製品を選択します。ここで、stock_quanity> 3、ここで、は写真であり、ここで、はallegroテーブル内の製品IDではありません。

現在、クエリには約10秒かかります。どうすれば最適化できるのかわかりません。

@解決済み

allegro.product_idとallegro.attributesにインデックスを追加しましたが、クエリにかかる時間は0.5秒未満です。助けてくれてありがとう

4

2 に答える 2

2

ものを取り除きEXISTS ( SELECT … ) = FALSEます。

それをこれらの行に沿って何かに変えてください:

LEFT JOIN allegro
          ON products_stock.products_id = allegro.product_id
         AND allegro.attributes = products_stock.products_stock_attributes
…
WHERE allegro.product_id IS NULL

MySQL ドキュメントのRewriting Subqueries as Joinsの章を参照してください。

その他の提案:

  • 使用しないテーブルと結合しないでください。products_to_categories
  • ISNULL(…) = FALSE書く代わりに… IS NOT NULL
于 2012-07-11T09:20:33.087 に答える
0

次の方法を試す前に、テーブル エンジンが innoDB に設定されていることと、適切にインデックスが作成されていることを確認してから、直接結合を試すことができます。最初に左側のテーブルを強制的に調べます。

もう 1 つの方法は、遅いクエリにmemcacheを使用することです。このメソッドを使用すると、クエリ結果を配列にキャッシュできます。これにより、db を頻繁にクエリする必要がなくなります。キャッシュされた結果は、指定された期間後に更新できます。

于 2012-07-11T09:36:07.580 に答える