优化我的sql索引多表连接

6ljaweal  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(237)

我在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

我想,这个问题在我的表的索引,但我不知道如何修复它们,有人能帮我吗?

v09wglhw

v09wglhw1#

大约有2%的行在 reciepts 有了正确的日期,选择的第二个执行计划(带直螺纹连接)似乎是正确的执行顺序。您应该能够通过添加以下覆盖索引对其进行优化:

reciept(date, sales)
 reciept_goods(recieptId, shopId, goodId, amount)

我假设 reciept_goods 目前是 (goodId, recieptId, shopId) (或 (goodId, shopId, receiptId) ). 你可以改成 recieptId, shopId, goodId (如果您查看例如表名,您可能还是希望这样做);在这种情况下,您不需要第二个索引(至少对于这个查询是这样)。我假设这个主键使mysql采用了较慢的执行计划(当然,假设它会更快),尽管有时这只是糟糕的统计数据,尤其是在测试服务器上。
有了这些覆盖索引,mysql应该采取更快的解释计划,即使没有 straight_join ,如果没有,只需再添加一次(尽管我想看看这两个执行计划)。还要检查说明计划中是否使用了这两个新索引,否则我可能会漏掉一列。

oyt4ldly

oyt4ldly2#

看来你得走几步了many:many tables? 许多人设计它们效率低下。
在这里,我列出了提高Map表效率的7个技巧。最重要的是使用综合指数。

相关问题