SELECT count(*) c FROM full_view WHERE verified > ( DATE (NOW()) - INTERVAL 30 DAY)
如果我运行该查询,则需要一瞬间但如果我切换比较运算符则需要一段时间。现在第一种方式count = 0,第二种方式count = 120000,但如果我只计算整个表也需要微秒。
但是有一些东西很有趣,因为如果查询完成它之后会超级快速地运行。 MySQL正在缓存查询或者其他什么?好吧,我不想依赖缓存来确保网站不会挂起。
这似乎是荒谬的:如果它可以快速计算大于特定日期的所有内容,为什么还需要更长的时间来计算相反的情况呢?无论哪种方式,它必须透视整个表格吗?它需要返回的只是一个数字,因此带宽不应成为问题。
解释查询:
1, 'SIMPLE', 'b', 'range', 'updated,verified_index', 'updated', '3', '', 28, 'Using where'`
1, 'SIMPLE', 'l', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'xyz_main.b.loc_id', 1, 'Using index'
1, 'SIMPLE', 'f', 'ALL', '', '', '', '', 2214, ''
编辑:
这可能有些兴趣,我在运行查询时发现了这个信息:
Handler_read_rnd_next:
Key_read_requests: 314393 vs 33(33是使用大于时所有统计数据的最大数字)
Handler_read_key: 104303 vs 1
绕过视图并直接在主表上运行查询消除了缓慢。那么我需要做些什么才能加快速度呢?视图基本上是这样的:
SELECT x, y, z, verified FROM table1 LEFT JOIN table2 on tab2_ID = table2.ID LEFT JOIN table3 on tab3_ID = table3.ID
解决: 弗兰基带领我走向正确的方向。第二个连接表(公司表)通过公司的全文名称加入。我最近才决定在该表中添加一个整数键。名称列应该被编入索引,但我可能会拙劣。无论如何,我重新组织了一切。我在主表中转换了外键以匹配公司表的整数ID,而不是完整的公司名称。我重新索引每个表中的列,然后我更新了视图以反映新的连接点。现在它可以在两个方向上立即运行。 :)所以我猜整数键是关键。问题已经消失,但我仍然觉得我原来的问题没有真正解决。
感谢您的帮助。
答案 0 :(得分:3)
请运行以下查询并发布结果。
EXPLAIN SELECT count(*) c
FROM full_view
WHERE verified > ( DATE (NOW()) - INTERVAL 30 DAY)
长期被遗忘的EXPLAIN
几乎总会带来一些东西! ; 强>)
编辑1:
这可能是进攻线:
1, 'SIMPLE', 'f', 'ALL', '', '', '', '', 2214, ''
ALL
表示存在全表扫描。
您可以进一步深入了解Explain
syntax on this diagram。
试着看看差异在哪里......
编辑2:
This doc will sure make things much clearer on the Explain
output. Please check it out.
编辑3:
解释命令的逐步分析。
1, 'SIMPLE', 'b', 'range', 'updated,verified_index', 'updated', '3', '', 28, 'Using where'`
1 - id
SIMPLE - simple select, not using sub-queries
b - table name
range - only rows that are in a given range are retrieved, using an index
updated,verified_index - are both possible keys
updated - was the key eventually used
3 - key lenght
'' - this is the ref column and would show which columns or constants are compared to the index name in the key column to select rows from the table.
28 - number of rows mysql believes it must examine to execute the query
Using where - self explanatory
答案 1 :(得分:2)
我的猜测是Date(Now())
的减法是需要很长时间才能处理的。对于已经小于verified
的{{1}}值,评估可能会被短路,因为此时它必须是假的(比较“大于”时)。
在您与“小于”进行比较的情况下,无论当前值如何,都必须在每种情况下减去日期时间,因为在评估之前无法将表达式逻辑推断为真或假日期时间减法
但这只是一个猜测 - 带上一粒盐。
答案 2 :(得分:1)
可能存在这样的情况:有统计数据告诉数据库引擎没有经过验证的记录> 30天前在这种情况下,它根本不需要读取表格,而是从统计直方图中获取信息。
答案 3 :(得分:0)
如果您在表格中的verified
上有索引,那么限制性更强的COUNT
(>一个)会更快。没有WHERE子句的COUNT(*)可以快速返回,因为可以从表/索引统计中收集计数。