mysql - 优化查询

标签 mysql sql indexing query-performance

我怎样才能使我的响应时间更快,大约平均响应时间为 0.2 秒(我的项目表中有 8039 条记录,我的跟踪表中有 81 条记录)

查询

 SELECT a.name, b.cnt  FROM `items` a  LEFT JOIN 
(SELECT guid, COUNT(*) cnt FROM tracking WHERE
date > UNIX_TIMESTAMP(NOW() - INTERVAL 1 day ) GROUP BY guid)  b ON
a.`id` = b.guid WHERE a.`type` = 'streaming' AND a.`state` = 1 
ORDER BY b.cnt DESC LIMIT 15 OFFSET 75

跟踪表结构

CREATE TABLE `tracking` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`guid` int(11) DEFAULT NULL,
`ip` int(11) NOT NULL,
`date` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i1` (`ip`,`guid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4303 DEFAULT CHARSET=latin1;

项目表结构

CREATE TABLE `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` int(11) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`embed` varchar(255) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`description` text,
`tags` varchar(255) DEFAULT NULL,
`date` int(11) DEFAULT NULL,
`vote_val_total` float DEFAULT '0',
`vote_total` float(11,0) DEFAULT '0',
`rate` float DEFAULT '0',
`icon` text CHARACTER SET ascii,
`state` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9258 DEFAULT CHARSET=latin1;

最佳答案

您的查询,如所写,没有多大意义。它会在您的两个表中生成所有可能的行组合,然后对它们进行分组。

你可能想要这个:

    SELECT a.*, b.cnt 
      FROM `items` a  
 LEFT JOIN (
              SELECT guid, COUNT(*) cnt 
                FROM tracking 
               WHERE `date` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 day) 
            GROUP BY guid
           )  b ON a.guid = b.guid
  ORDER BY b.cnt DESC

本次查询的海量数据来自比较大的tracking表。因此,您应该使用 (date, guid) 列为其添加复合索引。这将允许您的查询按 date 随机访问索引,然后扫描它以获取 guid 值。

 ALTER TABLE tracking ADD INDEX guid_summary (`date`, guid);

我想您会看到不错的性能提升。

专业提示:不要使用SELECT *。取而代之的是,给出你想要在结果集中出现的列的列表。例如,

SELECT a.guid, a.name, a.description, b.cnt  

为什么这很重要?

首先,它使您的软件在将来有人向您的表中添加列时更具弹性。

其次,它告诉 MySQL 服务器只发送您想要的信息。这可以显着提高性能,尤其是当您的表变大时。

关于mysql - 优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42144482/

相关文章:

php - 减少 mySQL 查询和时间

Mysql 范围检查而不是内部连接上的索引使用情况

indexing - WebStorm 保持索引略有变化

javascript - 如何使用表单自动生成指向根文件夹的php页面?

php - MySQL 如何从 URL 传递的参数中获取列

php - 按日期排序的 Wordpress PostViews 插件

MYSQL #1241 错误消息

SQL 对表值进行分类

sql-server - 拥有包含聚集索引中的主键的非聚集索引是否不好?

c# - 如何使用 C# 中的绑定(bind)源过滤从特定日期到特定日期的数据表?