SELECT pp.productID
FROM productPrices pp
LEFT JOIN products p ON pp.productID = p.productID
WHERE MATCH(p.productName) AGAINST('beef' IN NATURAL LANGUAGE MODE)
AND pp.storeID IN ('store-4513')
ORDER BY pp.currentPrice LIMIT 10 OFFSET 0;
我的这个查询在没有
ORDER BY
的情况下运行得非常快,但一旦添加它,运行需要 >20 秒。我为 FULLTEXT
添加了 productName
索引,为 INDEX
中的 storeID
添加了 productPrices
索引,为 INDEX
中的 currentPrice
添加了 productPrices
以及其他一些索引,但这没有帮助。这就是添加 EXPLAIN
时的样子。 productPrices
表有 100 万行,它说正在为其建立索引,这可能是问题所在。
+------+-------------+-------+--------+------------------------------------------------------------+------------------+---------+---------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+------------------------------------------------------------+------------------+---------+---------------------------+------+-------------+
| 1 | SIMPLE | pp | index | idx_storeID,idx_storeID_productID,idx_storeID_currentPrice | idx_currentPrice | 5 | NULL | 78 | Using where |
| 1 | SIMPLE | p | eq_ref | PRIMARY,idx_productID | PRIMARY | 52 | table.pp.productID | 1 | Using where |
+------+-------------+-------+--------+------------------------------------------------------------+------------------+---------+---------------------------+------+-------------+
我在一台速度较慢的服务器上运行 MariaDB 服务器,这可能是部分原因,但如果没有 ORDER BY,它的运行时间不到 0.2 秒。
通常不可能对给定的表有效地使用多个索引,因此理想情况下您拥有一个尽可能有帮助的索引。
仅考虑这一个查询,这里将是 (StoreID、currentPrice、productID) 上的索引。 StoreID 将其限制为可能查看的行,currentPrice 能够按价格顺序读取它们并在达到限制时停止,而 ProductID 则可以仅从索引记录连接产品表,而无需阅读主要产品价格记录。
正如评论中提到的,请注意,您的左连接表示不需要找到产品,但您的位置条件需要它,因此它实际上是内部连接。为了更好的可读性,您应该将其更改为内连接。