为什么我的MySQL连接速度慢?

时间:2014-03-14 02:13:22

标签: php mysql sql join

我有一个连接表的查询。这是select语句:

SELECT *, A.id AS id, 
       A.username AS username, 
       G.desc AS customer_desc, 
       H.id AS counter, 
       SUM( F.amount_paid ) 
FROM tblcheckin AS A
LEFT OUTER JOIN tblrate AS B ON B.id = A.rate_id
LEFT OUTER JOIN tblrefaccom_type AS C ON C.id = A.id
LEFT OUTER JOIN tblcust_bill AS D ON D.check_in_id = A.id
LEFT OUTER JOIN tblroom AS E ON E.room_no = A.room_id
LEFT OUTER JOIN tblpayment AS F ON F.check_in_id = A.id
LEFT OUTER JOIN tblrefcust_type AS G ON G.id = A.customer_desc
LEFT OUTER JOIN tblindex AS H ON A.id = H.check_in_id
WHERE A.check_out =  "0000-00-00 00:00:00"
GROUP BY F.check_in_id
ORDER BY check_out, check_in

结果:Showing rows 0 - 11 ( 12 total, Query took 7.4061 sec)

这是Explain SQL

enter image description here

这是我到目前为止所做的事情: 我设置了optimizer_search_depth = 0因为我认为它可以像Joining many tables in mySQL中提到的那样工作。

我在这里做错了什么?我感谢每一个反馈。谢谢。

更新。问题解决了。我从tblpayment,tblcust_bill和tblindex向check_in_id列添加了索引。这是新的Explain SQL

enter image description here

2 个答案:

答案 0 :(得分:3)

看看你的Explain,我可以看到几个连接需要全表扫描。您可能没有A.check_outD.check_in_idF.check_in_id的索引(这是基于相对行数的杀手)和H.check_in_id。这意味着必须扫描整个Darn表A,D,F和H才能找到相关的行。

索引这4行,查询次数应该会猛涨。

有人说,我很惊讶这已经不是很快,甚至没有优化。我在每个表中都看到了几万行 - 除非这些行非常庞大(顺便说一下糟糕的做法 - 将文本/ blob和大列分解成单独的表),你应该能够得到这些结果不到7秒。更像是我期望的70毫秒。我怀疑你必须调整你的mysql服务器设置 - 使用更多ram,增加缓冲区大小等。但这些索引应该有很大帮助。

答案 1 :(得分:2)

您似乎是左键加入了许多不满足您查询所需的表。这会有用吗,省去额外的桌子吗?

SELECT A.id AS id, 
       A.username AS username, 
       G.desc AS customer_desc, 
       H.id AS counter, 
       SUM( F.amount_paid ) 
FROM tblcheckin AS A
LEFT OUTER JOIN tblpayment AS F ON F.check_in_id = A.id
LEFT OUTER JOIN tblrefcust_type AS G ON G.id = A.customer_desc
LEFT OUTER JOIN tblindex AS H ON A.id = H.check_in_id
WHERE A.check_out =  "0000-00-00 00:00:00"
GROUP BY F.check_in_id
ORDER BY check_out, check_in

你正在使用一个讨厌的MySQL hackstension来GROUP BY。这样做。

GROUP BY A.id, A.username, G.desc, H.id

tblcheckin是一个有很多行的表吗?如果是这样,请确保check_out上有一个索引,并且它已声明为NOT NULL

确保在ON指令的JOIN子句中提到的列上有索引,即:

   tblpayment.check_in_id
   tblrefcust_type.id   (maybe already a primary key)
   tblindex.check_in_id

考虑在表中放置覆盖索引(多列索引)。这样,您可以从索引中完全满足您的查询所需的数据,这将节省查询查询磁盘驱动器时间。但是,很多索引可能会减慢插入和更新的速度。

   tblcheckin (cneck_out, id, customer_desc, username)
   tblpayment  (check_in_id, amount_paid)
   tblrefcust_type  (id, desc)
   tblindex        (check_in_id, id)