0

OrderBy が適用されていると、クエリの実行が非常に遅くなるという問題が発生しています。

私はすでに周りを見回して、クエリを SELECT * FROM (sql stuff) OrderBy フィールドで囲みました。これにより、時間が 22 秒から 10 秒に短縮されましたが、もっと速くする必要があります。SQL_NO_CACHE はテスト用です。

これにより、10 秒で 5866 レコードが返されます。orderby を削除すると、2 秒で戻ります。

SELECT 
     SQL_NO_CACHE * 
FROM
     (SELECT 
          SUM(
               MATCH(product_name) 
               AGAINST ('"Jeans"' IN BOOLEAN MODE) + 
               MATCH(store_name) 
               AGAINST ('"Jeans"' IN BOOLEAN MODE)
          ) AS searchScore,
          product_name,
          section_url,
          product_link_url,
          affiliate_store_product_id,
          store_url,
          product_date_added,
          product_image,
          product_image_path,
          product_sale_price,
          product_price,
          product_price_currency,
          product_url,
          product_id,
          product_channel_id,
          store_name,
          product_brand,
          colour_id,
          colour_name 
     FROM
          products 
          INNER JOIN stores 
               ON store_id = product_store_id 
          LEFT OUTER JOIN product_colours 
               ON product_colour_product_id = product_id 
          LEFT OUTER JOIN colours 
               ON colour_id = product_colour_colour_id 
          LEFT OUTER JOIN sections 
               ON product_channel_id = section_id 
          INNER JOIN storeShipping 
               ON storeShipping_store_id = store_id 
          INNER JOIN shipping_locations 
               ON shipping_location_id = storeShipping_shipping_location_id 
          JOIN product_categories 
               ON product_category_product_id = product_id 
          JOIN categories 
               ON category_id = product_category_category_id 
     WHERE (
               MATCH(product_name) AGAINST ('"Jeans"' IN BOOLEAN MODE) 
               OR MATCH(store_name) AGAINST ('"Jeans"' IN BOOLEAN MODE)
          ) 
          AND product_status = 1 
          AND category_status = 1 
          AND product_excluded = 0 
          AND product_feed_status = 1 
          AND store_status = 1 
          AND shipping_location_currency_code = 'AUD' 
          AND product_image_path IS NOT NULL 
          AND (
               product_channel_id = 1 
               OR product_channel_id = 2 
               OR product_channel_id = 3 
               OR product_channel_id = 4
          ) 
     GROUP BY product_url) AS T 
ORDER BY searchScore DESC ;

これがorderbyの説明です

+----+-------------+--------------------+--------+ -------------------------------------------------- -------------------------------------------------- -----------------------+------------------------+- ------+--------------------------------------------- ------+--------------------+---------------------------------------------- ---------------+
| | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ |
+----+-------------+--------------------+--------+ -------------------------------------------------- -------------------------------------------------- -----------------------+------------------------+- ------+--------------------------------------------- ------+--------------------+---------------------------------------------- ---------------+
| | 1 | プライマリ | <派生2> | すべて | \N | \N | \N | \N | 5866 | ファイルソートの使用 |
| | 2 | 派生 | 製品 | 参照 | PRIMARY,idx_product,idx_channel,idx_path,idx_store,idx_excluded,idx_status,idx_product_feed_status,idx_product_image_path | idx_status | 2 | | | 306688 | where を使用します。一時的な使用; ファイルソートの使用 |
| | 2 | 派生 | 店舗 | eq_ref | PRIMARY,idx_storestatus | プライマリ | 4 | products.product_store_id | 1 | where | の使用
| | 2 | 派生 | 製品カテゴリ | 参照 | PRIMARY,idx_category,idx_categoryproduct | idx_categoryproduct | 4 | products.product_id | 1 | | |
| | 2 | 派生 | カテゴリ | eq_ref | プライマリ、NewIndex1 | プライマリ | 4 | product_categories.product_category_category_id | 1 | where | の使用
| | 2 | 派生 | 製品の色 | 参照 | idx_colour製品 | idx_colour製品 | 5 | products.product_id | 2 | | |
| | 2 | 派生 | 色 | eq_ref | プライマリ | プライマリ | 4 | product_colours.product_colour_colour_id | 1 | | |
| | 2 | 派生 | ストア配送 | 参照 | idx_storeshippingstore,idx_storeshippinglocation | idx_storeshippingstore | 5 | store.store_id | 4 | where | の使用
| | 2 | 派生 | 配送先 | eq_ref | PRIMARY,idx_shippinglocation | プライマリ | 4 | storeShipping.storeShipping_shipping_location_id | 1 | where | の使用
| | 2 | 派生 | セクション | eq_ref | プライマリ | プライマリ | 4 | products.product_channel_id | 1 | | |
+----+-------------+--------------------+--------+ -------------------------------------------------- -------------------------------------------------- -----------------------+------------------------+- ------+--------------------------------------------- ------+--------------------+---------------------------------------------- ---------------+

そしてオーダーバイなしで

+--------+-------------+--------------------+----- ---+---------------------------------------------- -------------------------------------------------- ---------------------------+---------------------- --+--------------------+------------------------------------- --------------+--------+------------------------------------------ -------------------+
| | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ |
+--------+-------------+--------------------+----- ---+---------------------------------------------- -------------------------------------------------- ---------------------------+---------------------- --+--------------------+------------------------------------- --------------+--------+------------------------------------------ -------------------+
| | 1 | シンプル | 製品 | 参照 | PRIMARY,idx_product,idx_channel,idx_path,idx_store,idx_excluded,idx_status,idx_product_feed_status,idx_product_image_path | idx_status | 2 | 定数 | 306688 | where を使用します。一時的な使用; ファイルソートの使用 |
| | 1 | シンプル | 店舗 | eq_ref | PRIMARY,idx_storestatus | プライマリ | 4 | products.product_store_id | 1 | where | の使用
| | 1 | シンプル | 製品カテゴリ | 参照 | PRIMARY,idx_category,idx_categoryproduct | idx_categoryproduct | 4 | products.product_id | 1 | | |
| | 1 | シンプル | カテゴリ | eq_ref | プライマリ、NewIndex1 | プライマリ | 4 | product_categories.product_category_category_id | 1 | where | の使用
| | 1 | シンプル | 製品の色 | 参照 | idx_colour製品 | idx_colour製品 | 5 | products.product_id | 2 | | |
| | 1 | シンプル | 色 | eq_ref | プライマリ | プライマリ | 4 | product_colours.product_colour_colour_id | 1 | | |
| | 1 | シンプル | ストア配送 | 参照 | idx_storeshippingstore,idx_storeshippinglocation | idx_storeshippingstore | 5 | store.store_id | 4 | where | の使用
| | 1 | シンプル | 配送先 | eq_ref | PRIMARY,idx_shippinglocation | プライマリ | 4 | storeShipping.storeShipping_shipping_location_id | 1 | where | の使用
| | 1 | シンプル | セクション | eq_ref | プライマリ | プライマリ | 4 | products.product_channel_id | 1 | | |
+--------+-------------+--------------------+----- ---+---------------------------------------------- -------------------------------------------------- ---------------------------+---------------------- --+--------------------+------------------------------------- --------------+--------+------------------------------------------ -------------------+

私を後押しするためにあなたたちができることは何でも素晴らしいでしょう!

ありがとう!

4

2 に答える 2

0

クエリを少し変更しました。試してみませんか?また、これにより実行が大幅に改善されるのでINDEX、コラムもお寄せください。product_urlまた、可能であればINDEXproduct_namestore_name.

SELECT SUM(CASE WHEN product_name LIKE '%Jeans%' OR store_name LIKE '%Jeans%' 
                THEN 1 
           ELSE 0 END) AS searchScore,
       product_name, 
       section_url, 
       product_link_url, 
       affiliate_store_product_id, 
       store_url, 
       product_date_added, 
       product_image, 
       product_image_path, 
       product_sale_price, 
       product_price, 
       product_price_currency, 
       product_url, 
       product_id, 
       product_channel_id, 
       store_name, 
       product_brand, 
       colour_id, 
       colour_name 
FROM products 
             INNER JOIN stores ON store_id = product_store_id 
             LEFT OUTER JOIN product_colours ON product_colour_product_id = product_id 
             LEFT OUTER JOIN colours ON colour_id = product_colour_colour_id 
             LEFT OUTER JOIN sections ON product_channel_id = section_id 
             INNER JOIN storeShipping ON storeShipping_store_id = store_id 
             INNER JOIN shipping_locations ON shipping_location_id = storeShipping_shipping_location_id 
             JOIN product_categories ON product_category_product_id = product_id 
             JOIN categories ON category_id = product_category_category_id 
WHERE (product_name LIKE '%Jeans%' OR store_name LIKE '%Jeans%')
AND product_status = 1 
AND category_status = 1 
AND product_excluded = 0 
AND product_feed_status = 1 
AND store_status = 1 
AND shipping_location_currency_code = 'AUD' 
AND product_image_path IS NOT NULL 
AND product_channel_id IN (1, 2, 3, 4) 
GROUP BY product_url
ORDER BY searchScore
于 2012-05-29T11:31:38.467 に答える
0

searchScoreこれは、テーブル フィールドではなく、動的に集計された値です。したがって、MySQL はソートにインデックスを使用できず、代わりに FileSort を使用します。これはもちろん遅いです。

さて、最適化のヒントについて:

  1. product_url、、が 255 文字を超えない場合はproduct_name、 VARCHAR(255) または CHAR(255) を使用してください。store_nameそして、それproduct_urlがインデックス付きフィールドであることを確認してください(全文インデックスではなく、通常のインデックス)。実際には、3 つのフィールドすべてにインデックスを付ける必要があります。

  2. MATCH AGAINST本当に建設を使用する必要がありますか? そこで使用するとより速く動作しますREGEXPが、正確な要件はわかりません。

  3. 再びp.1に関連します-(VAR)CHAR(255)としてフィールドがあります-次に、WHERE+のすべてのフィールドの複合インデックスを追加しGROUP BYます。 product_image_path、product_channel_id、product_url。さらに、product_url別のインデックスとして持つ必要があります。

それが役立つことを願っています。私が提案した変更後、このクエリを 1 秒以内に実行する必要があります。

于 2012-05-29T11:36:29.933 に答える