在下面执行此查询时,它花费的时间太长。结果是记录太多,数据库中的记录可能更多。查询应返回大约 117.000 条记录。即在半年内进入数据库的记录量。
为什么这个查询成倍增加,导致数百万条记录?如果有人能告诉我我被卡住的地方,我会很高兴。
/* Formatted on 2011/08/05 17:09 (Formatter Plus v4.8.7) */
SELECT t2.flag, t3.reg_number, t1.reportdate, t1.latitude, t1.longitude,
t1.value2 course, ((t1.measspeed) * 3.6) / 1.852, t1.status alarms
FROM traffic t1, details t2, registernumbers t3
WHERE t1.mobileno = t2.mobile
AND t2.mobile = t3.mobileno
AND UPPER (t2.flag) = UPPER ('BEL')
AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
AND (latitude > 52 AND longitude > 2)
AND latitude > 48
OR (latitude < 52 AND longitude > 2)
OR (latitude > 52 AND longitude < 2)
ORDER BY reportdate DESC
Run Code Online (Sandbox Code Playgroud)
提前致谢,
马丁
执行过滤器的部分join
是t1.mobileno = t2.mobile AND t2.mobile = t3.mobileno
。为了使这一点合理,您可能需要以下三个陈述中的两个为真:
mobileno
是独一无二的 traffic
mobile
是独一无二的 details
mobileno
是独一无二的 registernumbers
因为连接返回的行比您预期的要多,所以我想情况并非如此。为了获得进一步的帮助,我们需要知道表的 DDL(特别是主键)
- -编辑
再想一想,我认为
WHERE t1.mobileno = t2.mobile
AND t2.mobile = t3.mobileno
AND UPPER (t2.flag) = UPPER ('BEL')
AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
AND (latitude > 52 AND longitude > 2)
AND latitude > 48
OR (latitude < 52 AND longitude > 2)
OR (latitude > 52 AND longitude < 2)
Run Code Online (Sandbox Code Playgroud)
需要有更多的括号:
WHERE t1.mobileno = t2.mobile
AND t2.mobile = t3.mobileno
AND UPPER (t2.flag) = UPPER ('BEL')
AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
AND (latitude > 52 AND longitude > 2)
AND ( latitude > 48
OR (latitude < 52 AND longitude > 2)
OR (latitude > 52 AND longitude < 2) )
Run Code Online (Sandbox Code Playgroud)
虽然有些条件似乎是多余的
您应该考虑使用更现代的INNER JOIN
语法。使用table1, table2, table3
经常导致笛卡尔积。table1 INNER JOIN table2 ON ... INNER JOIN table3 ON ...
然而,当您在逻辑上将连接标准与过滤标准分开时,它仍然是可能的。
虽然以下帖子专门针对 SQL Server,但其概念本质上是相同的:
您的 WHERE 子句不符合您的需要。AND 和 OR 操作在评估中具有相同的优先级,因此对于您列出的子句:
WHERE
t1.mobileno = t2.mobile
AND t2.mobile = t3.mobileno
AND UPPER (t2.flag) = UPPER ('BEL')
AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
AND (latitude > 52 AND longitude > 2)
AND latitude > 48
OR (latitude < 52 AND longitude > 2)
OR (latitude > 52 AND longitude < 2)
Run Code Online (Sandbox Code Playgroud)
你有 3 个条件被 OR'd 在一起......如果以下任何一项为真,则选择一条记录(我以相反的顺序列出它们以使问题更清楚):
您需要添加更多括号以强制在单个 AND 条件的上下文中评估 OR 条件,而不是让 OR 全部独立:
WHERE
t1.mobileno = t2.mobile
AND t2.mobile = t3.mobileno
AND UPPER (t2.flag) = UPPER ('BEL')
AND t1.reportdate BETWEEN '1/jan/2011' AND '1/jul/2011'
AND (latitude > 52 AND longitude > 2)
AND (
latitude > 48
OR (latitude < 52 AND longitude > 2)
OR (latitude > 52 AND longitude < 2)
)
Run Code Online (Sandbox Code Playgroud)