MySQL,如何更快地进行此查询?

时间:2016-10-27 16:48:50

标签: php mysql

我正在处理一个需要连接4个大表的查询。

表:

表1(ID,有效,价格1,价格2,名称,类别1,类别2) 这是包含所有产品的主表,32561行

table_2(ID,table_1_ID,房间,股票) 这是包含table_1中产品库存的表,此表可以多次使用table_1.ID,190400行

table_3(ID,table_1_ID,图片) 此表包含有关图片等产品的更多信息,某些产品没有这些产品,6546行

table_4(table_1_ID,view,type) 此表包含产品视图(每月视图)

我想要的是什么:

我正在尝试制作一个显示20个热门产品的查询。

条件:

  1. 它只能显示table_1.category1(A,B,C,D,E)中的产品
  2. 它只能显示有效的产品='T'
  3. 只能显示房间LJ0001和MS0001
  4. 的产品
  5. 它只能显示至少有1个库存的产品
  6. 代码:

    SELECT DISTINCT(Table_1.ID), Table_1.price1, Table_1.price2
       , Table_1.name, Table_1.category2, Table_3.images 
    FROM Table_1 
       LEFT JOIN Table_2 ON Table_1.ID=Table_2.table_1_ID 
       LEFT JOIN table_3 ON table_1.ID=table_3.table_1_ID 
       LEFT JOIN table_4 ON table_1.ID=table_4.table_1_ID 
    WHERE Table_1.active='T' 
       AND (Table_1.category1 LIKE 'A%' 
            OR Table_1.category1 LIKE 'B%' 
            OR Table_1.category1 LIKE 'C%' 
            OR Table_1.category1 LIKE 'D%' 
            OR Table_1.category1 LIKE 'E%'
           ) 
       AND table_2.room IN ('LJ0001','MS0001') 
       AND table_2.stock!=0 
    ORDER BY table_4.view DESC, Table_1.name 
    LIMIT 10 OFFSET 0
    

    注意:

    上面的代码有效。但这需要一段时间。我正在寻找可以加快速度的任何修复。

    任何帮助都会很好! 提前谢谢。

    EXPLAIN EXTENDED

    Link to image

2 个答案:

答案 0 :(得分:1)

使用下面更新的查询:

EXPLAIN EXTENDED
SELECT Table_1.ID, Table_1.price1, Table_1.price2
, Table_1.name, Table_1.category2, Table_3.images 
FROM Table_1 
LEFT JOIN Table_2 ON Table_1.ID=Table_2.table_1_ID 
LEFT JOIN table_3 ON table_1.ID=table_3.table_1_ID 
LEFT JOIN table_4 ON table_1.ID=table_4.table_1_ID 
WHERE Table_1.active='T' 
AND (Table_1.category1 = 'A' 
    OR Table_1.category1 = 'B' 
    OR Table_1.category1 = 'C' 
    OR Table_1.category1 = 'D' 
    OR Table_1.category1 = 'E'
    ) 
AND table_2.room IN ('LJ0001','MS0001') 
AND table_2.stock != 0 
ORDER BY table_4.view DESC, Table_1.name 
LIMIT 10 OFFSET 0

我删除了DISTINCT因为我认为table_1.ID是主键。如果是这样,则不需要将DISTINCT与主键一起使用,因为它已经是不同的。我还将LIKE运算符更改为=,因为它运行得更快。

然后,您需要确保已将所有联接字段(例如table_1_ID)编入索引。

您可能会在查询的顶部注意到EXPLAIN EXTENDED - 使用此子句,您将从db获得类似的内容:

           id: 1
           select_type: PRIMARY
           table: t1
           type: index
           possible_keys: NULL
           key: PRIMARY
           key_len: 4
           ref: NULL
           rows: 4
           filtered: 100.00
           Extra: Using index

您将获得每个表的说明。将列出查询中使用的所有外键,包括外键如果有索引等详细信息。您将找到更多信息here

答案 1 :(得分:0)

我认为我的修复可以帮到你。如果你可以在my.cnf中设置sql_cache_type = 2,你应该在查询中使用SQL_CACHE(如果没有带文本类型的字段),最好先做条件更容易"对于DB(LIKE与OR非常慢),如果使用INNODB,则可以为MySQL设置更大的缓冲池

SELECT SQL_CACHE DISTINCT(Table_1.ID), Table_1.price1, Table_1.price2
, Table_1.name, Table_1.category2, Table_3.images 
FROM Table_1 
LEFT JOIN Table_2 ON Table_1.ID=Table_2.table_1_ID 
LEFT JOIN table_3 ON table_1.ID=table_3.table_1_ID 
LEFT JOIN table_4 ON table_1.ID=table_4.table_1_ID 
WHERE Table_1.active='T' 
 AND table_2.stock!=0 
 AND table_2.room IN ('LJ0001','MS0001') 
 AND (Table_1.category1 LIKE 'A%' 
    OR Table_1.category1 LIKE 'B%' 
    OR Table_1.category1 LIKE 'C%' 
    OR Table_1.category1 LIKE 'D%' 
    OR Table_1.category1 LIKE 'E%'
   ) 
ORDER BY table_4.view DESC, Table_1.name 
LIMIT 10 OFFSET 0