[英]How can I speed up this SQL query?
I'm fairly new to SQL, and I'm trying to work out how to speed up a complex SQL query in postgres, perhaps by improving my use of indexes. 我对SQL还是很陌生,我正在尝试找出如何通过改善索引的使用来加快postgres中复杂SQL查询的速度。 This is the query:
这是查询:
SELECT
(SELECT ev.code FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :ak_0
AND ci.entry_id = t.id AND ci.value_id = ev.id) AS axis_0,
(SELECT ev.code FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :ak_1
AND ci.entry_id = t.id AND ci.value_id = ev.id) AS axis_1,
SUM(t.amount) as amount,
(SELECT ev.code FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :key_time_id
AND ci.entry_id = t.id AND ci.value_id = ev.id) AS time
FROM "entry" t
WHERE t.dataset_id = :dataset_id
AND t.id IN (SELECT ci.entry_id FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :k_0
AND ev.code = :v_0 AND ci.value_id = ev.id)
GROUP BY time, axis_0, axis_1
This is basically the database schema (as defined in Pylons): 这基本上是数据库架构(在Pylons中定义):
table_dataset = Table('dataset', meta.metadata,
Column('id', Integer, primary_key=True),
)
table_entry = Table('entry', meta.metadata,
Column('id', Integer, primary_key=True),
Column('dataset_id', Integer, ForeignKey('dataset.id')),
Column('amount', Float()),
)
table_classification_item = Table('classification_item', meta.metadata,
Column('id', Integer, primary_key=True),
Column('entry_id', Integer, ForeignKey('entry.id'), index=True),
Column('value_id', Integer, ForeignKey('enumeration_value.id'), index=True)
)
table_enumeration_value = Table('enumeration_value', meta.metadata,
Column('id', Integer, primary_key=True),
Column('key_id', Integer, ForeignKey('key.id'), index=True),
Column('code', UnicodeText(), index=True),
)
And it has indexes as follows: 它的索引如下:
"dataset_pkey" PRIMARY KEY, btree (id)
"entry_pkey" PRIMARY KEY, btree (id)
"classification_item_pkey" PRIMARY KEY, btree (id)
"ix_classification_item_entry_id" btree (entry_id)
"ix_classification_item_value_id" btree (value_id)
"enumeration_value_pkey" PRIMARY KEY, btree (id)
"ix_enumeration_value_code" btree (code)
"ix_enumeration_value_key_id" btree (key_id)
Am I missing any obvious index that would speed up the query? 我是否缺少任何明显的索引来加快查询速度? In particular:
尤其是:
amount
on entry
, or would that make no difference to SUM(t.amount) as amount
? amount
上entry
,或将是作出没有区别SUM(t.amount) as amount
? Thanks for your help. 谢谢你的帮助。 I know this is a pretty complex question, so please tell me if I can do anything to improve it.
我知道这是一个非常复杂的问题,所以请告诉我是否可以做任何改进。
------ UPDATE -------------- ------更新--------------
The output from EXPLAIN ANALYZE on the above query. 上面查询中EXPLAIN ANALYZE的输出 。
If the enumeration_value
table is small, I guess you can get some improvment by making axis_1
and axis_0
as join and add an extra index. 如果
enumeration_value
表很小,我想您可以通过将axis_1
和axis_0
为axis_0
并添加额外的索引来获得一些改进。
something like this (not tested) 像这样的东西(未经测试)
CREATE INDEX idx_ci_vi_ei ON classification_item(value_id, entry_id);
CREATE INDEX idx_id_ki ON enumeration_value(id, key_id);
SELECT
ci_0.code AS axis_0,
ci_1.code AS axis_1,
SUM(t.amount) as amount,
ci_t.code AS time
FROM
"entry" t,
(SELECT ev.code FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :ak_0 AND ci.value_id = ev.id) ci_0,
(SELECT ev.code FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :ak_1 AND ci.value_id = ev.id) ci_1,
(SELECT ev.code FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :key_time_id AND ci.value_id = ev.id) ci_t
WHERE t.dataset_id = :dataset_id
AND t.id IN (SELECT ci.entry_id FROM classification_item ci, enumeration_value ev
WHERE ev.key_id = :k_0
AND ev.code = :v_0 AND ci.value_id = ev.id)
AND t.id = ci_0.entry_id AND t.id = ci_1.entry_id AND t.id = ci_t.entry_id
GROUP BY time, axis_0, axis_1
EXPLAIN ANALYZE对查询计划有何评价?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.