我在mysql中有5个表。当我想执行查询时,它执行的时间太长了。我的表格结构如下:
receipt(count rows:23799640)receipt表结构
接收商品(计数行:39398989)接收商品表结构
良好(计数行:17514)良好的表结构
良好的\u分类(计数行:121)良好的\u分类表结构
零售类别(计数行:10)零售类别表结构
我的索引:
日期-->接收日期#1
接收商品索引-->接收商品.receiptId#1,接收商品.shopid#2,接收商品.goodid#3
类别#id-->良好。类别#id#1
我有下一个sql请求:
SELECT
R.shopId,
sales,
sum(Amount) as sum_amount,
count(distinct R.id) as count_reciept,
RC.id,
RC.name
FROM
reciept R
JOIN reciept_goods RG
ON R.id = RG.RecieptId
AND R.ShopID = RG.ShopId
JOIN good G
ON RG.GoodId = G.id
JOIN good_categories GC
ON G.category_id = GC.id
JOIN retail_category RC
ON GC.retail_category_id = RC.id
WHERE
R.date >= '2018-01-01 10:00:00'
GROUP BY
R.shopId,
R.sales,
RC.id
explain这个查询给出下一个结果:explain query and execution time=236秒
如果使用 straight_join good ON (good.id = reciept_goods.GoodId )
解释查询解释查询和执行时间=31秒
SELECT STRAIGHT_JOIN ... rest of query
我想,这个问题在我的表的索引,但我不知道如何修复它们,有人能帮我吗?
2条答案
按热度按时间v09wglhw1#
大约有2%的行在
reciepts
有了正确的日期,选择的第二个执行计划(带直螺纹连接)似乎是正确的执行顺序。您应该能够通过添加以下覆盖索引对其进行优化:我假设
reciept_goods
目前是(goodId, recieptId, shopId)
(或(goodId, shopId, receiptId)
). 你可以改成recieptId, shopId, goodId
(如果您查看例如表名,您可能还是希望这样做);在这种情况下,您不需要第二个索引(至少对于这个查询是这样)。我假设这个主键使mysql采用了较慢的执行计划(当然,假设它会更快),尽管有时这只是糟糕的统计数据,尤其是在测试服务器上。有了这些覆盖索引,mysql应该采取更快的解释计划,即使没有
straight_join
,如果没有,只需再添加一次(尽管我想看看这两个执行计划)。还要检查说明计划中是否使用了这两个新索引,否则我可能会漏掉一列。oyt4ldly2#
看来你得走几步了many:many tables? 许多人设计它们效率低下。
在这里,我列出了提高Map表效率的7个技巧。最重要的是使用综合指数。