简体   繁体   English

如何优化SQL查询?

[英]How optimize SQL query?

I have a query: 我有一个查询:

SELECT * FROM `trades`
WHERE `symbol` = 'ICX/BTC' AND `timestamp` >= :since AND `timestamp` <= :until
ORDER BY `timestamp`
LIMIT 50000

It's take long time to execute (more 5 min). 执行时间较长(超过5分钟)。 I have index by symbol and timestamp columns 我有按符号时间戳列索引

How I can optimize this query? 如何优化此查询?

For this query: 对于此查询:

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;

(which I just rewrite a bit so I can follow it more easily) (我只是重写了一点,所以我可以更轻松地遵循它)

You want an index on trades(symbol, timestamp) . 您想要trades(symbol, timestamp)指数trades(symbol, timestamp)

However, you appear to be selecting a very large number of rows, so this might still take a long time. 但是,您似乎选择了很多行,因此这可能仍需要很长时间。 The index should be used both for the WHERE clause and the ORDER BY . 该索引应同时用于WHERE子句和ORDER BY

In your query, you are retrieving data from just one table and your filter criteria are ... 在您的查询中,您仅从一张表中检索数据,并且您的过滤条件是...

  1. equality on symbol symbol平等

  2. range scan low-to-high on timestamp . 范围从低到高扫描timestamp

Therefore, (as Gordon mentioned) an index on two columns (symbol, timestamp) can satisfy your query, both the filtering and the ordering, quite efficiently. 因此,(如Gordon所述)两列(symbol, timestamp)上的索引可以非常有效地满足您的查询(包括过滤和排序)。 The query planner will do a random access operation on the index to the correct symbol and the starting timestamp, then read the index sequentially until the ending timestamp. 查询计划者将对索引执行随机访问操作,以获取正确的符号和起始时间戳,然后顺序读取索引,直到终止时间戳。 That's efficient. 那很有效。

But, your SELECT * may be holding you back on performance. 但是,您的SELECT *可能会阻碍您的性能。 Why? 为什么? If you used, for example, SELECT symbol, timestamp, cusip, name then you could create a so-called covering index on (symbol, timestamp, cusip, name) . 例如,如果使用SELECT symbol, timestamp, cusip, name则可以在(symbol, timestamp, cusip, name)上创建所谓的覆盖索引。 In that case, the entire query would be satisfied by scanning the index. 在这种情况下, 整个查询将通过扫描索引来满足。 That can be very efficient indeed. 这确实可以非常有效。

Pro tip Avoid SELECT * , both for software stability and performance reasons. 提示出于软件稳定性和性能的原因,请避免使用SELECT *

Pro tip Don't add extra indexes to a table unless you know they will help particular queries. 温馨提示不要在表中添加额外的索引,除非您知道它们会帮助特定的查询。 MySQL only uses a single index for each table in a query or subquery. MySQL仅对查询或子查询中的每个表使用单个索引。 Neither an index on just timestamp or just symbol will help much: MySQL still has to examine a lot of rows to satisfy your filtering criteria. 仅在timestamp或仅在symbol上的索引都无济于事:MySQL仍必须检查很多行才能满足过滤条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM