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的解释

+----+--------------+--------+--------+ -------------------------------------------------- -------------------------------------------------- ------------------------------------+-------------+- --------+----------------------------------------- ---------+--------+------------------------------- ---------------+
| 编号 | 选择类型 | 表| 类型 | 可能的键 | 关键 | 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 | 使用哪里;使用临时的;使用文件排序 |
| 2 | 派生 | 商店 | eq_ref | PRIMARY,idx_storestatus | 初级 | 4 | products.product_store_id | 1 | 使用位置 |
| 2 | 派生 | 产品类别 | 参考 | PRIMARY,idx_category,idx_categoryproduct | idx_categoryproduct | 4 | products.product_id | 1 | |
| 2 | 派生 | 类别 | eq_ref | 初级,新索引1 | 初级 | 4 | product_categories.product_category_category_id | 1 | 使用位置 |
| 2 | 派生 | 产品颜色 | 参考 | idx_colourproduct | idx_colourproduct | 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_id | 4 | 使用位置 |
| 2 | 派生 | 运输地点 | eq_ref | PRIMARY,idx_shippinglocation | 初级 | 4 | storeShipping.storeShipping_shipping_location_id | 1 | 使用位置 |
| 2 | 派生 | 部分 | eq_ref | 初级 | 初级 | 4 | products.product_channel_id | 1 | |
+----+--------------+--------+--------+ -------------------------------------------------- -------------------------------------------------- ------------------------------------+-------------+- --------+----------------------------------------- ---------+--------+------------------------------- ---------------+

没有orderby

+--------+-------------+--------+-- ---+---------------------------------------------------------- -------------------------------------------------- ---------------------------------------+------------------------ --+---------+-------------------------- -------------+--------+--------------- ------------------+
| 编号 | 选择类型 | 表| 类型 | 可能的键 | 关键 | 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 | 使用哪里;使用临时的;使用文件排序 |
| 1 | 简单 | 商店 | eq_ref | PRIMARY,idx_storestatus | 初级 | 4 | products.product_store_id | 1 | 使用位置 |
| 1 | 简单 | 产品类别 | 参考 | PRIMARY,idx_category,idx_categoryproduct | idx_categoryproduct | 4 | products.product_id | 1 | |
| 1 | 简单 | 类别 | eq_ref | 初级,新索引1 | 初级 | 4 | product_categories.product_category_category_id | 1 | 使用位置 |
| 1 | 简单 | 产品颜色 | 参考 | idx_colourproduct | idx_colourproduct | 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_id | 4 | 使用位置 |
| 1 | 简单 | 运输地点 | eq_ref | PRIMARY,idx_shippinglocation | 初级 | 4 | storeShipping.storeShipping_shipping_location_id | 1 | 使用位置 |
| 1 | 简单 | 部分 | eq_ref | 初级 | 初级 | 4 | products.product_channel_id | 1 | |
+--------+-------------+--------+-- ---+---------------------------------------------------------- -------------------------------------------------- ---------------------------------------+------------------------ --+---------+-------------------------- -------------+--------+--------------- ------------------+

你们能做的任何事情都可以给我一个鼓励,那就太好了!

谢谢!

4

2 回答 2

0

I have modified your query a little. Can you try it? Also please INDEX the column product_url this will improve the execution a lot. Also if possible INDEX the columns product_name and store_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, product_name,store_name不大于 255 个字符 - 然后为它们使用 VARCHAR(255) 甚至 CHAR(255) 。并确保product_url是索引字段(不是全文索引,而是普通索引)。实际上,所有 3 个字段都必须被索引。

  2. 你确定你需要使用MATCH AGAINST建筑吗?如果你在REGEXP那里使用它会更快,但我不知道确切的要求。

  3. 它再次与 p.1 相关 - 您的字段为 (VAR)CHAR(255) - 然后在WHERE+中添加所有字段的复合索引GROUP BY,我的意思是:product_name, store_name, product_status, category_status, product_excluded, product_feed_status, store_status, shipping_location_currency_mode, product_image_path、product_channel_id、product_url。另外,你必须有product_url一个单独的索引。

希望它会有所帮助。在我提出修改后,您应该在不到一秒的时间内执行此查询。

于 2012-05-29T11:36:29.933 回答