【发布时间】:2021-09-25 14:37:53
【问题描述】:
我正在尝试分析为什么LIMIT 0,1 的以下查询比LIMIT 0,100 慢
我已添加 SQL_NO_CACHE 用于测试目的。
查询:
SELECT
SQL_NO_CACHE SQL_CALC_FOUND_ROWS wp_posts.*,
low_stock_amount_meta.meta_value AS low_stock_amount
FROM
wp_posts
LEFT JOIN wp_wc_product_meta_lookup wc_product_meta_lookup ON wp_posts.ID = wc_product_meta_lookup.product_id
LEFT JOIN wp_postmeta AS low_stock_amount_meta ON wp_posts.ID = low_stock_amount_meta.post_id
AND low_stock_amount_meta.meta_key = '_low_stock_amount'
WHERE
1 = 1
AND wp_posts.post_type IN ('product', 'product_variation')
AND (
(wp_posts.post_status = 'publish')
)
AND wc_product_meta_lookup.stock_quantity IS NOT NULL
AND wc_product_meta_lookup.stock_status IN('instock', 'outofstock')
AND (
(
low_stock_amount_meta.meta_value > ''
AND wc_product_meta_lookup.stock_quantity <= CAST(
low_stock_amount_meta.meta_value AS SIGNED
)
)
OR (
(
low_stock_amount_meta.meta_value IS NULL
OR low_stock_amount_meta.meta_value <= ''
)
AND wc_product_meta_lookup.stock_quantity <= 2
)
)
ORDER BY
wp_posts.ID DESC
LIMIT
0, 1
解释显示完全相同的输出
1 SIMPLE wp_posts index PRIMARY,type_status_date PRIMARY 8 NULL 27071 Using where
1 SIMPLE low_stock_amount_meta ref post_id,meta_key meta_key 767 const 1 Using where
1 SIMPLE wc_product_meta_lookup eq_ref PRIMARY,stock_status,stock_quantity,product_id PRIMARY 8 woocommerce-admin.wp_posts.ID 1 Using where
LIMIT 0,1的平均查询时间为350ms
LIMIT 0,100的平均查询时间为7ms
从LIMIT 0,17开始查询性能变快
按照question 中的建议,我在 order by 子句中添加了另一列,但这会在解释输出中触发 Using filesort
Order by wp_posts.post_date, wp_posts.ID desc
1 SIMPLE wp_posts ALL PRIMARY,type_status_date NULL NULL NULL 27071 Using where; Using filesort
1 SIMPLE low_stock_amount_meta ref post_id,meta_key meta_key 767 const 1 Using where
1 SIMPLE wc_product_meta_lookup eq_ref PRIMARY,stock_status,stock_quantity,product_id PRIMARY 8 woocommerce-admin.wp_posts.ID 1 Using where
有没有办法在不改变索引的情况下解决这个问题?为什么会这样?
有趣的是查询时间从LIMIT 0,17 开始有所改善。我不知道为什么 17 在这里是一个神奇的数字。
更新 1:我刚刚尝试添加 FORCE INDEX(PRIMARY),现在 LIMIT 0,100 与 LIMIT 0,1 smh 具有相同的性能
【问题讨论】:
-
通常第二次最好。 第一次时间包括从磁盘获取内容。
-
@RickJames 但我有 SQL_NO_CACHE,区别是 350 毫秒和 7 毫秒,即使是第一次运行 LIMIT 0,17 也很快。
-
缓冲池也是缓存。在新系统上,直到第一次查询之后才加载任何帖子和 postmeta。因此,如果第一次查询测试花费了几秒钟,“平均值”将异常高,即使其余的非常低。 (而且,是的,最好避免“查询缓存”。)
-
@RickJames 我明白你在说什么,但它仍然没有解释为什么 LIMIT 0, 17 比 0,1 快得多的问题,即使对于第一个查询也是如此。我什至尝试重新启动系统以使系统变冷。
-
请再次确认您的执行计划实际上是相同的,因为只有在它们不同时才会发生这种情况。另外,您提到您添加了“强制索引(主)”(究竟在哪里?),那么查询是同样快还是同样慢?如果强制执行计划中显示所有 3 个索引会发生什么?
标签: mysql sql wordpress query-optimization limit