我有两个mysql表,其结构如下:
mysql> describe symbol;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| symbol | varchar(250) | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> describe price;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| id_symbol | int(11) | NO | MUL | NULL | |
| date | date | NO | MUL | NULL | |
| price | double | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)我必须查询价格表才能得到包含两个符号的N个价格的列表(比较它们)
这是一个样本结果:
DATE SYMBOL 1 SYMBOL 2
2011-01-01 100 23
2011-01-02 92 26
2011-01-03 89 50因此,我需要找到两者的相同数据,并返回他们的价格。我已经创建了一个查询,它似乎完成了任务,但可能不是很优化。
SELECT *
FROM price AS a
JOIN price AS b ON a.date = b.date
WHERE a.id_symbol = 1 AND b.id_symbol = 2
ORDER BY a.date DESC
LIMIT 100你认为如何?
我是否可以优化查询,执行某些操作(或者可能更改表结构上的某些内容)?
编辑:
这是EXPLAIN {query}的结果。
mysql> EXPLAIN SELECT *
-> FROM price AS a
-> JOIN price AS b ON a.date = b.date
-> WHERE a.id_symbol = 1 AND b.id_symbol = 2
-> ORDER BY a.date DESC
-> LIMIT 100;
+----+-------------+-------+------+----------------+-----------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------+-----------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | a | ref | date,id_symbol | id_symbol | 4 | const | 921 | Using where; Using filesort |
| 1 | SIMPLE | b | ref | date,id_symbol | id_symbol | 4 | const | 966 | Using where |
+----+-------------+-------+------+----------------+-----------+---------+-------+------+-----------------------------+
2 rows in set (0.03 sec)你认为如何?
然后
..。解释“行”列上的921和966是什么?如果我数一下符号1和符号2的价格,我得到: 912和912:--这是什么?
(是的,我的错误-我必须用我想要的列来改变*)
发布于 2011-08-19 17:33:31
基于有限的信息,您所能做的就是在id_symbol ASC, date DESC上创建一个索引,并可能将*限制在您需要的列上。
最大的“加速”可能是将两个查询合并为一个查询,然后只运行该查询并解析结果集,而不是运行一个查询来获取所有的符号对,然后对每个符号对进行不同的查询。您没有提供原始查询,因此不可能建议这个组合查询。
发布于 2011-08-19 18:07:55
这是您最初的查询
SELECT *
FROM price AS a
JOIN price AS b ON a.date = b.date
WHERE a.id_symbol = 1 AND b.id_symbol = 2
ORDER BY a.date DESC
LIMIT 100;你需要做两个主要的改变:
更改#1 :重构查询
只使用键,确定位置,先订购,最后再加入
SELECT A.date,GROUP_CONCAT(A.price ORDER BY A.id_symbol) prices
FROM price A
INNER JOIN
(
SELECT BB.* FROM
(
SELECT DISTINCT date FROM
(
SELECT AAAA.date FROM
(SELECT date FROM price WHERE id_symbol = 1) AAAA
INNER JOIN
(SELECT date FROM price WHERE id_symbol = 2) BBBB
USING (date)
ORDER BY AAAA.date
) AAA ORDER BY date DESC LIMIT 100
) AA
INNER JOIN
(SELECT date,id_symbol FROM price WHERE id_symbol in (1,2)) BB
USING (date)
ORDER BY BB.date DESC,BB.id_symbol
) B
USING (date,id_symbol) GROUP BY date;变更#2 :创建索引以支持REFACTORED查询
ALTER TABLE price ADD INDEX symbol_date_id_ndx (id_symbol,date,id);
ALTER TABLE price ADD INDEX date_id_ndx (date,symbol_id);试试看!!
发布于 2011-08-19 17:31:12
除了可能非常合适的关于过早优化的评论之外,您是否尝试过使用EXPLAIN (http://dev.mysql.com/doc/refman/5.1/en/using-explain.html)来查看查询是如何实际执行的?从这里开始,您可能需要查看添加索引。
https://stackoverflow.com/questions/7125148
复制相似问题