我刚刚从Access更改为mySQL。我有几张桌子,名为“Veranstaltung”和“Veranstaltung_User”。我希望得到用户所有的所有事件(= Veranstaltung),用户正在查看的那个事件。
我使用以下声明做了这个
SELECT VID, Bezeichnung, Datum
FROM tbl_Veranstaltung
WHERE year(Datum) = 2012
AND VID <> 613
AND VID IN (SELECT BewerbID
FROM Veranstaltung_User
WHERE UserID IN (SELECT UserID
FROM Veranstaltung_User
WHERE BewerbID = 613)
AND UserID <> 0)
ORDER BY Datum
在Access中,这个查询非常快 - 在mySQL中它需要44,56秒 - 太多了; - )
如何优化我的语句以加快查询速度? (mySQL&gt; 5,table ware MyISAM)
感谢您的帮助
答案 0 :(得分:2)
两个变化:
1.使用JOIN而不是嵌套的IN子句
2.使用<= and >
代替YEAR()
函数
改变1
的优势在于,有时IN性能可能比预期的差,并且嵌套它们会使exascerabate。
更改2
的优点是它允许索引查找以查找一系列记录。其中 - 使用YEAR()来扫描整个表/索引。
两者都假设您有适当的索引。
SELECT
V.VID, V.Bezeichnung, V.Datum
FROM
tbl_Veranstaltung V
INNER JOIN
Veranstaltung_User VUser
ON VUser.BewerbID = V.VID
INNER JOIN
Veranstaltung_User VUser2
VUser.UserID = VUser2.UserID
WHERE
V.Datum >= '20120101'
AND V.Datum < '20130101'
AND V.VID <> 613
AND VUser.UserID <> 0
AND VUser2.BewerbID = 613
ORDER BY
Datum
答案 1 :(得分:0)
此查询可能需要调整,已尝试对表格布局进行一些假设+将根据提供的任何说明进行更新
SELECT
v.VID,
v.Bezeichnung,
v.Datum
FROM tbl_Veranstaltung AS v
INNER JOIN Veranstaltung_User AS vu
ON vu.BewerbID = v.VID
AND vu.UserID = [THIS USER ID]
AND vu.BewerbID <> 613
// Used a BETWEEN so that MySQL does not need to apply YEAR() to every row
WHERE v.Datum BETWEEN DATE('2012-01-01') AND DATE('2012-12-30');
我还建议以下两个索引
CREATE INDEX dateIndex ON tbl_Veranstaltung (`Datum`);
CREATE INDEX userBewerIndex ON Veranstaltung_User (`BewerbID`,`UserID`);
之后,通过比较,查询应该是即时的
编辑如果我逐字地查看源查询,我会使用以下
SELECT
v.VID,
v.Bezeichnung,
v.Datum
FROM tbl_Veranstaltung AS v
INNER JOIN Veranstaltung_User AS vu
ON vu.BewerbID = v.VID
AND vu.BewerbID <> 613
AND vu.UserID <> 0
WHERE v.Datum BETWEEN DATE('2012-01-01') AND DATE('2012-12-30');