在我们的应用程序中,我们尝试为给定的一组参数找到最佳匹配。我们已将这些行分成不同的质量组,这些质量组与总参数集的一部分相匹配。为了匹配这些不同的组,我们有多个select查询,如果没有找到结果,我们随后会查询这些查询,现在我们决定使用UNION ALL和LIMIT 1一起加入它们。来自多个查询的第一个现有行
SET @size = 4, @price = 18, @category = 'NEW', @weight = 20, @origin = 'France';
(SELECT * FROM product_catalog WHERE quality = 'A1' AND size = @size AND price = @price AND category = @category AND weight = @weight AND origin = @origin LIMIT 1)
UNION ALL
(SELECT * FROM product_catalog WHERE quality = 'A2' AND size = @size AND price = @price AND category = @category AND origin = @origin LIMIT 1)
UNION ALL
(SELECT * FROM product_catalog WHERE quality = 'A3' AND price = @price AND category = @category AND weight = @weight AND origin = @origin LIMIT 1)
UNION ALL
(SELECT * FROM product_catalog WHERE quality = 'A4' AND price = @price AND category = @category AND origin = @origin LIMIT 1)
UNION ALL
... SOME MORE SELECTS ...
LIMIT 1
现在查询确实按预期运行,但它执行方式比我们当前的解决方案更差。我认为这与MySQL可能首先执行UNION语句然后意识到它只需要返回第一个语句有关。
你有什么建议可以帮助加快查询速度吗?你认为有可能将查询重写到一个存储过程,该存储过程将检查每个查询的结果,并在找到结果时立即返回该结果。这会加快查询速度吗?
MySQL将评估所有部件。但有些想法:a)如果没有总体顺序,你的最后一个限制可以带任意联合的* ANY *未指定的随机行,所以它不等同于尝试第一个查询,并且只有在没有找到任何时才继续下一个查询。 b)如果为所有组合添加索引,则此查询应该在<0.2s内运行。不知道它是否已经这样做了,并且您只需要它以每分钟1000次的速度运行得更快,但除此之外,您应该首先检查索引。c)'或','按质量排序',只有一个限制可能会比'union'更快,这取决于索引。 – Solarflare
谢谢你的回答。我担心你的观点a),但我不确定是否属于这种情况。此外,查询确实运行速度在0.2秒以下,事实上甚至更快,但正如您所猜测的,我总共需要运行该查询数百万次。我做了一些重写,现在我有一个解决方案,它使用一些'ORDER BY'和'(size = @size或size IS NULL)'魔法来结合查询。 –