我的查询是这样的
SELECT * FROM tbl1
JOIN tbl2 ON something = something
WHERE 1 AND (tbl2.date = '$date' OR ('$date' BETWEEN tbl1.planA AND tbl1.planB ))
当我运行此查询时,它比例如此查询
慢得多SELECT * FROM tbl1
JOIN tbl2 ON something = something
WHERE 1 AND ('$date' BETWEEN tbl1.planA AND tbl1.planB )
或
SELECT * FROM tbl1
JOIN tbl2 ON something = something
WHERE 1 AND tbl2.date = '$date'
在localhost中,第一个查询大约需要0.7秒,第二个查询大约需要0.012秒,第三个查询大约需要0.008秒。
我的问题是你如何优化这个?如果我目前在表中有1000行,显示第一个查询需要0.7秒,如果我有10.000行,则需要7秒?与第二次查询(0.12秒)和第三次查询(0.08)相比,这是一个巨大的减速。
我尝试过添加索引,但结果没有什么不同。
由于
编辑:此应用程序仅在本地运行,因此无需担心网络速度。
抱歉,我没有包含EXPLAIN,因为我的真实查询要复杂得多(约5个连接)。但是连接(我认为)并不重要,因为我已经尝试省略它们并且仍然得到与上面大致相同的结果。
日期属于tbl1,planA和planB属于tbl2。我已经尝试将索引添加到tbl1.date,tbl2.planA和tbl2.planB,但结果无关紧要。
通过架构你的意思是MyISAM还是InnoDB?这是MyISAM。
好的,我会立即发布我的查询。希望这不是那么令人困惑。
SELECT *
FROM tb_joborder jo
LEFT JOIN tb_project p ON jo.project_id = p.project_id
LEFT JOIN tb_customer c ON p.customer_id = c.customer_id
LEFT JOIN tb_dispatch d ON jo.joborder_id = d.joborder_id
LEFT JOIN tb_joborderitem ji ON jo.joborder_id = ji.joborder_id
LEFT JOIN tb_mix m ON ji.mix_id = m.mix_id
WHERE dispatch_date = '2011-01-11'
OR '2011-01-11'
BETWEEN planA
AND planB
GROUP BY jo.joborder_id
ORDER BY customer_name ASC
描述输出
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE jo ALL NULL NULL NULL NULL 453 Using temporary; Using filesort
1 SIMPLE p eq_ref PRIMARY PRIMARY 4 db_dexada.jo.project_id 1
1 SIMPLE c eq_ref PRIMARY PRIMARY 4 db_dexada.p.customer_id 1
1 SIMPLE d ALL NULL NULL NULL NULL 2048 Using where
1 SIMPLE ji ALL NULL NULL NULL NULL 455
1 SIMPLE m eq_ref PRIMARY PRIMARY 4 db_dexada.ji.mix_id 1
答案 0 :(得分:1)
您可以使用UNION合并第二和第三查询的结果。
More关于UNION。
答案 1 :(得分:1)
首先想到的是将两者联合起来:
SELECT * FROM tbl1
JOIN tbl2 ON something = something
WHERE 1 AND ('$date' BETWEEN planA AND planB )
UNION ALL
SELECT * FROM tbl1
JOIN tbl2 ON something = something
WHERE 1 AND date = '$date'
您提供的优化太少。我们对您的数据结构一无所知。
答案 2 :(得分:0)
即使大多数慢查询通常是由于查询本身或使用过的表的索引设置,您也可以尝试使用MySQL Query Profiler找出瓶颈所在。自5.0.37版以来,它已经在MySQL中实现。
在开始查询之前,请使用以下语句激活探查器:
mysql> set profiling=1;
现在执行您的长查询。
用
mysql> show profiles;
您现在可以找出长查询的内部编号(查询编号)。
如果您现在执行以下查询,您将获得有关花费多长时间的详细信息:
mysql> show profile for query (insert query number here);
(example output)
+--------------------+------------+
| Status | Duration |
+--------------------+------------+
| (initialization) | 0.00005000 |
| Opening tables | 0.00006000 |
| System lock | 0.00000500 |
| Table lock | 0.00001200 |
| init | 0.00002500 |
| optimizing | 0.00001000 |
| statistics | 0.00009200 |
| preparing | 0.00003700 |
| executing | 0.00000400 |
| Sending data | 0.00066600 |
| end | 0.00000700 |
| query end | 0.00000400 |
| freeing items | 0.00001800 |
| closing tables | 0.00000400 |
| logging slow query | 0.00000500 |
+--------------------+------------+
这是一种更通用的管理方法,但可以帮助缩小甚至找出导致查询速度慢的原因。
可以在MySQL文章中找到关于如何使用MySQL Query Profiler的好教程{。{3}}。