事实上,我没能想出(或研究)一个解决这个问题的办法,这意味着我要么太笨了,看不懂这些文件,要么事实上这是一个复杂的问题。
在一个相当大的数据库中,我经常需要这样的查询:
SELECT ... WHERE condition GROUP BY something;
这需要几分之一秒的时间来完成。所以我把它放在一个Angular :
CREATE VIEW view_x AS SELECT ... GROUP BY something;
当我这么做的时候
SELECT * FROM view_x WHERE condition;
要花一分钟以上才能完成。现在很容易看出原因:在普通选择中,db引擎首先从数百万条记录中选择几百个结果,然后仅对匹配的记录进行聚合和分组。在使用视图时,它似乎首先对整个数据集进行求值,对所有内容进行聚合和分组,然后只返回满足条件的记录,并丢弃了代价高昂的其余记录。
是否有更智能的视图解决方案,或者每次都必须使用全选?
谢谢。
编辑:以下是视图的原始sql代码:
CREATE VIEW v_status1 AS SELECT
FROM_UNIXTIME(J.ts_start) AS job_start,
J.id AS job_id, J.carrier, J.n_wafers,
count(W.id) AS n
FROM job AS J
JOIN wafer AS W ON J.id=W.job_id
GROUP BY J.carrier, J.n_wafers, W.status_id;
桌上作业:100k条记录,桌上晶圆:2m条记录。
比较这些查询:
SELECT * FROM v_status1 WHERE carrier LIKE 'W96L00%'; -- very slow
而在视图定义中,在GROUPBY子句之前使用where子句进行相同的select。
一些附加信息:查询产生9条记录。使用视图执行需要19秒。根据mysql workbench,使用直接查询需要0.000秒。
当我将直接查询中的where子句替换为查询末尾具有相同条件的having子句时,我将在与使用视图的查询相同的执行时间结束。
是的,我忘了分组中的一些栏目。把它们放进去,没什么区别。
最小示例(5秒执行时间):
CREATE VIEW v_status2 AS SELECT
job_id,
status_id,
count(id) AS n
FROM wafer
GROUP BY job_id, status_id;
在给定作业id的情况下产生2条记录
1条答案
按热度按时间ih99xse11#
好吧,我做了显而易见的事情,让mysql解释一下。输出如下。我的解释是我一直怀疑的:mysql首先构建一个临时表,进行所有艰苦的聚合和分组工作,然后只选择符合选择标准的行。换句话说,mysql不够智能,无法首先分析视图,以找到在哪里可以有效地剔除原始数据集,而只处理剩余的记录。
顺便说一句,这与连接和索引无关。您可以看到任何足够大的两列表的效果。