我已经编写了一个连接三个不同表的查询。表的粗略描述如下:
Table 1: account_data
columns: id(pk), property_id(fk), account_id(fk), value, status
No Of Data: around 30 milions
Table 2: account
columns: id(pk), service_id(fk), status
No Of Data: around 5 milions
Table 3: property
columns: id(pk), create_analytics(index), status, uri
No Of Data: few hundreds查询如下:
SELECT ad.value, p.uri, count(ad.id)
FROM account_data ad
INNER JOIN property p ON ad.property_id = p.id AND (p.status = 1)
INNER JOIN account ac ON ad.account_id = ac.id AND (ac.status = 1)
WHERE (p.create_analytics = '1' AND ac.service_id = ?) AND (ad.status = 1)
GROUP BY ad.property_id, ad.value一开始,查询花费的时间太长。在'create_analytics‘列上创建索引后,它明显下降。
但是,查询花费的时间太长(超过3分钟)。我尝试在group by列(property_id和value)上创建索引,在“status”列上创建索引,但这两种方法都没有改善。
只是想知道,有没有其他方法可以重写这个查询,使它更快?或者我错过了创建索引、变更单会有帮助的地方吗?
期待您的所有想法/建议来解决这个问题。提前谢谢。
发布于 2014-07-06 07:03:07
此外,如果当前的create_analytics是VARCHAR,请尝试将其更改为CHAR,或者,如果该字段中的字符串种类有限,则将其更改为ENUM。
MySQL很灵活,可以在不使用的字符上节省空间,但是MySql必须查看是否有其他字段可以修复,以便Varchars可以预先知道行的宽度。
确保你所有的连接都是同一类型的,我猜你的ids是INT,确保你没有在某个地方混合使用BIGINTs。
最后,尝试将creating_analytics移动到联接部分,以便为WHERE子句提供较小的结果集。
发布于 2014-07-06 07:34:45
删除您当前拥有的索引(PKs除外),并尝试在以下内容上添加(复合)索引:
account_data (property_id,status)
property (status,create_analytics)
account (status,service_id)发布于 2014-07-06 06:39:07
这在很大程度上取决于您期望数据更改的频率以及您正在处理的其他约束,但是您可以尝试使用实例化视图以及视图本身上的索引。注:您可以在MySQL中的实体化视图上配置刷新策略。
来自http://www.fromdual.com/mysql-materialized-views;
刷新实例化视图
实例化视图可以以不同的类型进行刷新。可以刷新它们:
之后)
可以通过以下方式进行刷新:
从scratch)
通过将改变信息存储在日志表中。此外,还可以生成一些快照或时间延迟状态:
https://stackoverflow.com/questions/24590979
复制相似问题