【问题标题】:MYSQL need a faster queryMYSQL 需要更快的查询
【发布时间】:2012-06-29 15:28:10
【问题描述】:

我有两张表,其中一张将 id 与评级相匹配,其中一张的 id 包含大约 15 列中的实际数据。在数据表中,id 列有一个索引,在评级表中,id 是主键,评级是索引的。我想选择数据,但只能从具有正面评价的行中选择。为此,我正在使用查询

SELECT * FROM data_table 
  INNER JOIN rating_table ON data_table.id = rating_table.id
  WHERE rating > 0

但由于某种原因,这大约需要 0.35 秒,这对我来说似乎非常长。数据表中大约有 90,000 行,而评级表中大约有 5,000 行,这需要不到十分之一秒的时间……我怎样才能以不同的方式索引或以不同的方式查询来加快这项任务?

编辑: 分析后,它给了我以下信息。请注意,我认为它已被缓存,因此查询返回的速度比以前快得多,但即便如此这可能对某人有用

0.000012 starting   
0.000053 checking query cache for query     
0.000014 Opening tables     
0.000006 System lock    
0.000027 Table lock     
0.000044 init   
0.000018 optimizing     
0.000060 statistics     
0.000016 preparing  
0.000004 executing  
0.004916 Sending data   
0.000007 end    
0.000003 query end  
0.002271 freeing items  
0.000009 storing result in query cache  
0.000002 logging slow query     
0.000004 cleaning up    

所以我看到很多时间都花在了发送数据上……我怎样才能加快这部分的速度?

【问题讨论】:

  • 三个问题:1)data_table.idrating_table.id是同一个数据类型吗? 2) 除了索引id 字段之外,您是否也索引了rating? 3) 您是否分析过该声明以查明持续时间是否不是由其他原因引起的(例如将数据发送回客户端)?
  • 创建索引。它将大大提高您的查询响应时间。
  • 是的,我在问题中说 rating 已经有一个索引,并且两个表中的 id 具有相同的数据类型。我现在在 php myadmin 中运行它,所以时间实际上花在了 mysql 上。还有你所说的查询计划是什么意思?
  • MySQL 仅支持原始标准,但请参阅dev.mysql.com/doc/refman/5.6/en/execution-plan-information.html。查询计划是如何执行特定的 RA 操作:表扫描?哈希连接? [哪个] 使用了索引? (它还包含其他信息,如大小估计——错误的大小/基数估计会导致计划选择不当。)
  • 只选择那些需要的列而不是 * 和评级?它是一列吗?使用 data_table.rating > 0 你能提供一些关于sqlfiddle.com的示例数据

标签: mysql optimization indexing query-optimization


【解决方案1】:

对您的问题没有确切的解决方案,但在没有看到实际表结构的情况下提供了一些建议:正确分析您的查询。

MySQL 有一个内置分析器,它允许您非常详细地查看查询的哪一部分花费了多少时间。

根据您的情况,请按照以下步骤操作:

(1) 执行您的查询。

(2) 找出查询 id 进行分析:

SHOW PROFILES;

它会返回如下内容:

Query_ID |  Duration | Query
---------+-----------+-----------------------
   2     | 0.0006200 | SHOW STATUS
   3     | 0.3600000 | (your query here)
  ...    | ...       | ...

现在您知道查询 ID 是 (3)。

(3) 分析查询。

SHOW PROFILE FOR QUERY 3;   // example 

这将为您返回详细信息,可能如下所示:

Status                          | Duration
--------------------------------+-------------------
starting                        | 0.000010
checking query cache for query  | 0.000078
Opening tables                  | 0.000051
System lock                     | 0.000003
Table lock                      | 0.000008
init                            | 0.000036
optimizing                      | 0.000020
statistics                      | 0.000013
preparing                       | 0.000015
Creating tmp table              | 0.000028
executing                       | 0.000602
Copying to tmp table            | 0.000176
Sorting result                  | 0.000043
Sending data                    | 0.080032
end                             | 0.000004
removing tmp table              | 0.000024
end                             | 0.000006
query end                       | 0.000003
freeing items                   | 0.000148
removing tmp table              | 0.000019
closing tables                  | 0.000005
logging slow query              | 0.000003
cleaning up                     | 0.000004

在这个例子中,大部分时间实际上是花在将数据从服务器发送回客户端。

如果您已经这样做了,也许可以更新您的问题以显示结果。也可以添加数据结构。

【讨论】:

  • 好的,我刚刚发布了结果,但我认为它已被缓存,因为这次它返回得更快。它仍然可能有用。谢谢你告诉我这个我以前从未使用过探查器。
  • 请在执行查询之前重置查询缓存,否则我们只会看到它从缓存中收到数据:RESET QUERY CACHE;
  • @hackartist,请记住,Sending data 实际上非常具有欺骗性。这不仅仅是将数据发送到客户端所花费的时间。这是从读取第一行到完成将最后一行发送给客户端的时间。换句话说,将数据发送到客户端所花费的时间可能不到该值的 1%。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
相关资源
最近更新 更多