我有以下查询:
SELECT disTINCT f1.match_static_id,f2.comments_no,f2.maxtimestamp,users.username,users.id,matches_of_comments.localteam_name,matches_of_comments.visitorteam_name,matches_of_comments.localteam_goals,matches_of_comments.visitorteam_goals,matches_of_comments.match_status,new_iddaa.iddaa_code
FROM comments AS f1
INNER JOIN (
             SELECT match_static_id,MAX( TIMESTAMP ) maxtimestamp,COUNT( match_static_id ) AS comments_no
             FROM comments
             GROUP BY match_static_id
          ) AS f2 ON f1.match_static_id = f2.match_static_id 
                  AND f1.timestamp = f2.maxtimestamp
INNER JOIN users ON users.id = f1.user_id
INNER JOIN matches_of_comments ON matches_of_comments.match_id = f2.match_static_id
LEFT JOIN new_iddaa ON new_iddaa.match_id = matches_of_comments.match_id
WHERE matches_of_comments.flag =1
ORDER BY f2.maxtimestamp DESC

这是该查询的EXPLAIN计划:

+----+-------------+---------------------+--------+-----------------------------------+-----------+---------+------------------------------------------+-------+------------------------------------------------+
| id | select_type |        table        |  type  |           possible_keys           |    key    | key_len |                   ref                    | rows  |                     extra                      |
+----+-------------+---------------------+--------+-----------------------------------+-----------+---------+------------------------------------------+-------+------------------------------------------------+
|  1 | PRIMARY     | <derived2>          | ALL    | NULL                              | NULL      | NULL    | NULL                                     |   542 | Using temporary; Using filesort                |
|  1 | PRIMARY     | f1                  | ref    | timestamp,match_static_id,user_id | timestamp | 4       | f2.maxtimestamp                          |     1 | Using where                                    |
|  1 | PRIMARY     | users               | eq_ref | PRIMARY                           | PRIMARY   | 4       | skormix_db1.f1.user_id                   |     1 |                                                |
|  1 | PRIMARY     | matches_of_comments | ALL    | match_id                          | NULL      | NULL    | NULL                                     | 20873 | Range checked for each record (index map: 0x8) |
|  1 | PRIMARY     | new_iddaa           | ref    | match_id                          | match_id  | 4       | skormix_db1.matches_of_comments.match_id |     1 |                                                |
|  2 | DERIVED     | comments            | ALL    | NULL                              | NULL      | NULL    | NULL                                     |   933 | Using temporary; Using filesort                |
+----+-------------+---------------------+--------+-----------------------------------+-----------+---------+------------------------------------------+-------+------------------------------------------------+

如果此匹配至少有一条评论,我会使用此查询来获取匹配信息.
我得到了团队的名字,代码(iddaa代码),评论数量,最后一个commrnt的timstamp,最后一条评论的作者.
我有一个大型数据库,预计在接下来的几个月内会更大,我对MySQL查询非常新,我想确保我从一开始就使用优化查询,所以我想知道如何阅读这解释了使查询更好,更快的信息.

我看到表中有很多地方虽然我已经建立了它们但没有使用索引.
我也看到在表列中派生,我不知道如何使这个查询更快,以及如何摆脱filesort因为我不能为派生查询制作索引?

我用索引(键)写下查询中使用表的结构,我希望能提前得到一些提示或简单的答案.

注释(f1)表结构是:

CREATE TABLE `comments` (
 `id` int(25) NOT NULL AUTO_INCREMENT,`comments` text COLLATE utf8_unicode_ci NOT NULL,`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`date` date NOT NULL,`time` time NOT NULL,`match_static_id` int(25) NOT NULL,`ip` varchar(255) CHaraCTER SET latin1 NOT NULL,`comments_yes_or_no` int(25) NOT NULL,`user_id` int(25) NOT NULL,PRIMARY KEY (`id`),KEY `timestamp` (`timestamp`),KEY `match_static_id` (`match_static_id`),KEY `user_id` (`user_id`)
) ENGINE=MyISAM AUTO_INCREMENT=935 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

用户表结构是:

CREATE TABLE `users` (
 `id` int(25) NOT NULL AUTO_INCREMENT,`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`gender` int(25) NOT NULL,`first_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`last_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`avatar` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`alert` int(25) NOT NULL,`daily_tahmin` int(25) NOT NULL,`monthly_tahmin` int(25) NOT NULL,`admin` int(25) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=995 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

matches_of_comments_结构是:

CREATE TABLE `matches_of_comments` (
 `id` int(25) NOT NULL AUTO_INCREMENT,`en_tournament_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`tournament_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`country_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`match_status` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`match_time` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`match_date` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`static_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`fix_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`match_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`localteam_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`localteam_goals` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`localteam_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`visitorteam_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`visitorteam_goals` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`visitorteam_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`ht_score` varchar(255) COLLATE utf8_unicode_ci NOT NULL,`flag` int(25) NOT NULL,KEY `match_status` (`match_status`),KEY `match_date` (`match_date`),KEY `match_id` (`match_id`),KEY `localteam_id` (`localteam_id`),KEY `visitorteam_id` (`visitorteam_id`),KEY `flag` (`flag`)
) ENGINE=MyISAM AUTO_INCREMENT=237790 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

new_iddaa表结构是:

CREATE TABLE `new_iddaa` (
 `id` int(25) NOT NULL AUTO_INCREMENT,`match_id` int(25) NOT NULL,`iddaa_code` int(25) NOT NULL,`tv_channel` varchar(255) CHaraCTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,`skormix_tahmin` varchar(255) CHaraCTER SET utf8 NOT NULL,KEY `match_id` (`match_id`)
) ENGINE=MyISAM AUTO_INCREMENT=8191 DEFAULT CHARSET=latin1
在讨论选项之前,先从更紧迫的问题开始.

第一个直接问题是:

SELECT disTINCT …

选择区别很慢.非常非常慢:它基本上比较了您的集合返回的每一行的每个字段.当有一个ID确保每行唯一时,自然存在优化的空间,但是你自己的查询看起来并不像它提供任何这样的可能性:最好是来自matches_of_comments和new_iddaa的元组.

要解决此问题,请在两个或多个部分中断查询,并仅获取您正在执行的操作所需的内容.这似乎是按照最新评论日期对matches_of_comments进行排序,然后从用户和new_iddaa获取额外的化妆品数据.

下一个是imho最大的问题:

INNER JOIN (
         SELECT match_static_id,COUNT( match_static_id ) AS comments_no
         FROM comments
         GROUP BY match_static_id
      ) AS f2 ON f1.match_static_id = f2.match_static_id 
              AND f1.timestamp = f2.maxtimestamp

您正在加入一个聚合,其中包含一个(match_static_id,timestamp)元组上的表,该表没有索引,并且获取了一个巨大的集合.你有一个有保障的合并加入 – 不是你想要的.

最后一个引人注目的问题是:

ORDER BY f2.maxtimestamp DESC

首先,你没有限制.这意味着你要构建,排序并返回一个庞大的集合.当然,您正在对这些数据进行分页,因此在查询中通过添加limit子句来执行此操作.

添加限制后,您需要考虑添加额外行的内容以及应如何排序.根据您的架构,我想new_iddaa.您是否以这样的方式对事物进行分页,即后一个信息需要成为该查询的一部分以及它返回的行数?我想不到,因为你对这些行的排序方式显然不感兴趣.

扫描您的架构后,会弹出另外一个:

`match_id` varchar(255)

引用它的行是整数,对吗?所以它也应该是一个整数,以避免将varchars转换为int的开销,反之亦然,并允许在任何一种情况下使用索引.

虽然与此特定查询无关,但以下两个字段也需要注意并正确转换:

`tournament_id` varchar(255)
`match_time` varchar(255)
`match_date` varchar(255)
`static_id` varchar(255)
`fix_id` varchar(255)
`localteam_id` varchar(255)
`visitorteam_id` varchar(255)

在改进查询…

在我阅读时,您按最新评论订购了matches_of_comments.您还需要评论数量,因此我们首先要这样做.假设您正在对前十个中的前十个进行分页,则查询如下所示:

SELECT match_static_id,COUNT( match_static_id ) AS comments_no
FROM comments
GROUP BY match_static_id
ORDER BY maxtimestamp DESC
LIMIT 10 OFFSET 0

就这样.

它为您提供10个ID – 如果您增加限制,则更多.在您的应用程序中循环它们并构建一个in(…)子句,允许您根据需要从其他表中获取每个单独的数据位;你可以用一个或几个查询做到这一点,这很重要.关键是要避免加入该聚合,以便索引可用于后续查询.

通过完全删除上述查询,您可以更加显着地改进事物.

为此,请向matches_of_comments添加三个字段,即last_comment_timestamp,last_comment_user_id和num_comments.使用触发器维护它们,并在(flag,last_comment_timestamp)上添加索引.这将允许您运行以下有效查询:

SELECT matches_of_comments.static_id,matches_of_comments.num_comments,matches_of_comments.last_comment_timestamp,matches_of_comments.last_comment_user_id,matches_of_comments.match_status
FROM matches_of_comments
WHERE matches_of_comments.flag = 1
ORDER BY matches_of_comments.last_comment_timestamp DESC
LIMIT 10 OFFSET 0

然后,您只需要从用户和new_iddaa中选择所需的数据 – 使用具有in(…)子句的单独查询,如前所述.

php – 如何根据解释结果改进此查询的更多相关文章

  1. 视频流 – 使用视频工具箱解码iOS 8中的h264

    需要解码h264流并获取像素缓冲区我知道iOS8上的视频工具箱可能1.如何将h264流转换为CMSampleBufferRef?

  2. ios – 访问文件属性与访问sqlite记录

    >看到上述结果后,我决定选择attributesOfItemAtPath方法.还有什么我不是考虑传递sqlite?

  3. ios – NSTimeInterval到unix时间戳

    我从cmmotionmanager获取CMDeviceMotion对象.CMDeviceMotion的一个属性是时间戳,表示为NSTimeInterval.根据文档,这允许“亚毫秒”时间戳精度.不幸的是,NSTimeInterval是自上次设备启动以来计算的,对以原始形式使用它提出了重大挑战.有没有人有一个工作代码将此NSTimeInterval转换为类似时间戳的Unix?解决方法在将磁力计值与CoreMotion事件进行比较时,我遇到了类似的问题.如果要转换这些NSTimeIntervals,您只需要计

  4. ios – 更改JSQMessagesViewController中的时间戳逻辑

    SOMessaging一天一天怎么样?

  5. 如何从iOS中的CMSampleBufferRef获取相机数据当前捕获的时间戳

    我开发和iOS应用程序,将捕获的相机数据保存到一个文件,我使用捕获CMSampleBufferRef,并将编码为H264格式,帧将使用AVAssetWriter保存到文件.我遵循示例源代码来创建此应用程序:http://www.gdcl.co.uk//2013/02/20/iOS-Video-Encoding.html现在我想获得保存的视频帧的时间戳来创建一个新的电影文件,为此我做了以下事情1)找

  6. ios – 如何维护两个不同设备之间的时钟会话?

    我正在研究iOS应用程序,它需要在接受两个设备用户时在两个设备之间维持时钟计时器会话?但我不确定如何在两台设备上都没有时间缺陷的情况下实现这一目标?

  7. Swift开发用到的一些工具类

  8. Swift&amp;Cocoa实战之数据类型:时间日期

    时间日期NSDate在Objective-C中,可以使用如下的代码创建一个UTC的时间:但是在Swift中,如果使用如下方式:获取到的会是本地时间。

  9. swift - DateUtil

  10. swift 移动支付之【微信支付】开发步骤

    //向微信注册WXApi.registerapp2.发送预支付数据预支付数据由后台返回,格式如下[plain]viewplaincopyprint?{"appid":"wxxxxxxxxxxx","noncestr":"Hk8dsZoMOdTXGjkJ","package":"Sign=WXPay","partnerid":"01001010110","prepayid":"wx2016050000000000000000000000","sign":"B4879FFFA8B65522A04034E2D0

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部