Mysql 如何优化SQL查询?
我有一个问题:Mysql 如何优化SQL查询?,mysql,sql,Mysql,Sql,我有一个问题: SELECT * FROM `trades` WHERE `symbol` = 'ICX/BTC' AND `timestamp` >= :since AND `timestamp` <= :until ORDER BY `timestamp` LIMIT 50000 SELECT*FROM`trades` 其中'symbol`='ICX/BTC'和'timestamp`>=:since和'timestamp`用于此查询: SELECT t.* FROM trade
SELECT * FROM `trades`
WHERE `symbol` = 'ICX/BTC' AND `timestamp` >= :since AND `timestamp` <= :until
ORDER BY `timestamp`
LIMIT 50000
SELECT*FROM`trades`
其中'symbol`='ICX/BTC'和'timestamp`>=:since和'timestamp`用于此查询:
SELECT t.*
FROM trades AS t
WHERE t.symbol = 'ICX/BTC' AND t.timestamp >= :since AND t.timestamp <= :until
ORDER BY t.timestamp
LIMIT 50000;
选择t*
从作为t的交易
其中t.symbol='ICX/BTC'和t.timestamp>=:由于和t.timestamp在查询中,您仅从一个表中检索数据,您的筛选条件是
符号上的相等性
时间戳上的范围扫描从低到高
因此,(正如Gordon提到的)两列(符号,时间戳)
上的索引可以非常有效地满足您的查询,包括筛选和排序。查询计划器将对索引执行随机访问操作,以找到正确的符号和开始时间戳,然后按顺序读取索引,直到结束时间戳。这很有效
但是,您的SELECT*
可能会影响性能。为什么?例如,如果使用选择symbol、timestamp、cusip、name
,则可以在(symbol、timestamp、cusip、name)
上创建所谓的覆盖索引。在这种情况下,可以通过扫描索引来满足整个查询。这确实是非常有效的
Pro提示出于软件稳定性和性能原因,避免选择*
Pro-tip不要向表中添加额外的索引,除非您知道它们有助于特定的查询。MySQL只对查询或子查询中的每个表使用一个索引。在时间戳
或符号
上建立索引都不会有多大帮助:MySQL仍然需要检查很多行以满足您的筛选条件。您需要交易
的所有属性吗?缩短执行时间的一种方法是只选择所需的属性。换句话说,写SELECT*FROM
更具体。ORDER BY
确实是减慢速度的因素,按所有50K行排序是查询中的大部分工作。将其放入(可缓存)视图。请发布表定义(SHOW CREATE table trades
)和解释结果。这是SQL性能问题的最少信息。此响应中的查询与问题中的查询不同吗?只是出于好奇问一下,因为它们在我看来是一样的,除了你的是用缩写的t?另外,在查询中,t在哪里定义?表中的行数超过4000万行。是的,我尝试使用symbol,以便t表别名执行与您的查询相同的操作。。但是,您应该养成在MySQL中使用表别名或完全量化的表名的习惯,这样,如果您使用相关子查询或内部查询@dan,MySQL就永远不会混淆列。但是为什么要编辑这个答案来“修复”它呢?作为一个编辑似乎有点自由,应该由OP来进行这种编辑。不管怎么说,我最初只是问,因为我不完全理解答案,试图得到澄清来学习。值得一提的是,戈登·林诺夫和雷蒙德·尼兰德都是这里的长期参与者。我认为他们互相支持是件好事。而且,一个5万行的结果集肯定会消耗很多资源,包括DBMS和客户端程序。你能把它减少到一个更小的数字吗?我试着设置5K,1K,500的限制-没有变化