我正在处理一个需要连接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个热门产品的查询。
条件:
代码:
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
答案 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