简体   繁体   English

如何使这个复杂的查询更快[MySQL]?

[英]How to make this complicated query faster [MySQL]?

I have the next query: 我有下一个查询:

SELECT JL.j_id, COUNT(*) as total
FROM j_log JL
WHERE JL.log_time > '20120205164008'
AND JL.j_id IN (
     SELECT j_id 
     FROM j 
     WHERE checked = '1' 
     AND expires >= '20120207164008'
) GROUP BY JL.j_id ORDER BY total DESC LIMIT 3

j table has big structure 100 fields and 248986 rows inside it. j表具有100个字段和248986行的大结构。

next KEY's are present in it 里面有下一个钥匙

  PRIMARY KEY (`j_id`),
  KEY `expires` (`expires`),
  KEY `checked` (`checked`),
  KEY `checked_2` (`checked`,`expires`)

j_log table has about 63000000 records and the next structure j_log表具有大约63000000条记录和下一个结构

CREATE TABLE `j_log` (
  `j_id` int(11) NOT NULL DEFAULT '0',
  `member_id` int(11) DEFAULT NULL,
  `ip` int(10) unsigned NOT NULL DEFAULT '0',
  `log_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  KEY `j_id` (`j_id`),
  KEY `log_time` (`log_time`),
  KEY `ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

so the considered query wants to get top3 of most visited j_id instances 因此考虑的查询希望获得访问量最大的j_id实例的top3

this is the plan 这是计划

+----+--------------------+-------+-----------------+-----------------------------------+---------+---------+------+----------+----------+----------------------------------------------+
| id | select_type        | table | type            | possible_keys                     | key     | key_len | ref  | rows     | filtered | Extra                                        |
+----+--------------------+-------+-----------------+-----------------------------------+---------+---------+------+----------+----------+----------------------------------------------+
|  1 | PRIMARY            | JL    | index           | log_time                          | j_id    | 4       | NULL | 63914602 |     0.36 | Using where; Using temporary; Using filesort |
|  2 | DEPENDENT SUBQUERY | j     | unique_subquery | PRIMARY,expires,checked,checked_2 | PRIMARY | 4       | func |        1 |   100.00 | Using where                                  |
+----+--------------------+-------+-----------------+-----------------------------------+---------+---------+------+----------+----------+----------------------------------------------+

Some times it could take up for 15!!! 有时可能会占用15个!!! minutes. 分钟。

Is there any way how to make faster ? 有什么办法可以使速度更快?

SELECT JL.j_id, COUNT(*) as total
FROM j_log JL
INNER JOIN j
  ON JL.j_id = j.j_id
  AND j.checked = '1'
  AND j.expires >= '20120207164008'
WHERE JL.log_time > '20120205164008'
GROUP BY JL.j_id
ORDER BY total
DESC LIMIT 3

Will this be faster? 这样会更快吗?

  • Why do you use a subquery? 为什么使用子查询?
  • Why is checked a string? 为什么要checked字符串? ('1' instead of just 1) (“ 1”而不是1)
  • Why do you compare jl.log_time and j.expires diffrently ( > vs >= ) 为什么要比较jl.log_timej.expires> vs >=

How about this query 这个查询怎么样

     SELECT j.j_id, COUNT(jl.j_id) as total
       FROM j
  LEFT JOIN j_log jl ON (jl.j_id = j.j_id AND jl.checked = '1' AND jl.log_time > '20120205164008')
      WHERE j.expires >= '20120207164008'

   GROUP BY j.j_id 
   ORDER BY total DESC 
      LIMIT 3

Make sure j_id is the PRIMARY KEY for both tables and put an index on j.expires and jl.checked and jl.logtime. 确保j_id是两个表的PRIMARY KEY ,并在j.expires和jl.checked和jl.logtime上放置索引。 Also make sure the field checked is optimized. 还要确保checked的字段已优化。 I'm not sure what the possible values can be, but I assume it's a boolean field. 我不确定可能的值是多少,但是我认为这是一个布尔字段。 So rather make the field_type BIT or use an ENUM 因此,宁可将field_type设为BIT或使用ENUM

Edit 编辑

Also you should convert the fields j.expires and jl.log_time to better fields. 另外,您应该将字段j.expiresjl.log_time转换为更好的字段。 I think it is just a varchar now, looking at the current value you use: 20120205164008. Convert this into a DATETIME field (but don't just convert the tables because you will lose the data). 我认为现在只是一个varchar ,查看您使用的当前值:20120205164008。将其转换为DATETIME字段(但不要只是转换表,因为这样会丢失数据)。

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

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