MYSQL 查询慢 SELECT DISTINCT
Posted
技术标签:
【中文标题】MYSQL 查询慢 SELECT DISTINCT【英文标题】:MYSQL query slow SELECT DISTINCT 【发布时间】:2021-07-06 00:02:04 【问题描述】:我想输出最近 3 天我的分类广告中最常用的搜索项
我有一个额外的表格,我在其中保存所有搜索项以及日期和一个计数器,如果再次使用搜索(以及将来使用它所使用的类别页面),计数器会增加
这可行,但速度低于预期。
关于如何提高性能的任何想法?
更新: 似乎复制到临时表会导致问题 - 我该如何更改?
SQL 看起来像:
SELECT distinct search_item
FROM `tb_search`
WHERE added >= ( CURDATE() - INTERVAL 3 DAY )
ORDER BY count DESC
LIMIT 0,20
解释:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tb_search range added added 3 NULL 4537 Using index condition; Using temporary; Using filesort...
但是很慢,php脚本的完整40ms执行时间需要12ms所以25%
表结构(Innodb) 23.000 条记录
tb_search
Column Type Null Default Links to Comments Media (MIME) type
id (Primary) bigint(20) No
search_item varchar(30) No
category varchar(30) Yes NULL
added date No
count smallint(6) No
Indexes
Keyname Type Unique Packed Column Cardinality Collation Null Comment
PRIMARY BTREE Yes No id 23744 A No
search_item BTREE No No search_item 11872 A No
added BTREE No No added 44 A No
空间使用
数据 1.5 MiB 索引 1.9 MiB 开销 466.0 MiB
开销有问题吗?我怎样才能摆脱它?优化所有表并没有改变它。 db 总大小为 86MB
**Detailed profile**
1 Starting 48 µs
2 Checking Permissions 6 µs
3 Opening Tables 14 µs
4 After Opening Tables 13 µs
5 System Lock 5 µs
6 Table Lock 3 µs
7 After Table Lock 5 µs
8 Init 20 µs
9 Optimizing 11 µs
10 Statistics 85 µs
11 Preparing 34 µs
12 Executing 4 µs
13 Creating Tmp Table 24 µs
**14 Copying To Tmp Table 9.7 ms**
15 Sorting Result 218 µs
16 Sending Data 18 µs
17 End 4 µs
18 Removing Tmp Table 9 µs
19 End 5 µs
20 Query End 7 µs
21 Closing Tables 9 µs
22 Freeing Items 8 µs
23 Updating Status 21 µs
24 Cleaning Up 4 µs
Summary by stateDocumentation
State
Total Time
% Time
Calls
ø Time
Starting 48 µs 0.47% 1 48 µs
Checking Permissions 6 µs 0.06% 1 6 µs
Opening Tables 14 µs 0.14% 1 14 µs
After Opening Tables 13 µs 0.13% 1 13 µs
System Lock 5 µs 0.05% 1 5 µs
Table Lock 3 µs 0.03% 1 3 µs
After Table Lock 5 µs 0.05% 1 5 µs
Init 20 µs 0.19% 1 20 µs
Optimizing 11 µs 0.11% 1 11 µs
Statistics 85 µs 0.83% 1 85 µs
Preparing 34 µs 0.33% 1 34 µs
Executing 4 µs 0.04% 1 4 µs
Creating Tmp Table 24 µs 0.23% 1 24 µs
**Copying To Tmp Table 9.7 ms 94.42% 1 9.7 ms**
Sorting Result 218 µs 2.12% 1 218 µs
Sending Data 18 µs 0.17% 1 18 µs
End 4 µs 0.04% 2 2 µs
Removing Tmp Table 9 µs 0.09% 1 9 µs
Query End 7 µs 0.07% 1 7 µs
Closing Tables 9 µs 0.09% 1 9 µs
Freeing Items 8 µs 0.08% 1 8 µs
Updating Status 21 µs 0.20% 1 21 µs
Cleaning Up 4 µs 0.04% 1 4 µs
表结构
-- phpMyAdmin SQL Dump
-- version 5.0.3
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Generation Time: Apr 10, 2021 at 11:03 AM
-- Server version: 5.5.68-MariaDB
-- PHP Version: 7.3.27
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `terraristik_main`
--
-- --------------------------------------------------------
--
-- Table structure for table `tb_search`
--
CREATE TABLE `tb_search` (
`id` bigint(20) UNSIGNED NOT NULL,
`search_item` varchar(30) NOT NULL,
`category` varchar(30) DEFAULT NULL,
`added` date NOT NULL,
`count` smallint(6) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tb_search`
--
ALTER TABLE `tb_search`
ADD PRIMARY KEY (`id`),
ADD KEY `search_item` (`search_item`),
ADD KEY `added` (`added`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `tb_search`
--
ALTER TABLE `tb_search`
MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
【问题讨论】:
也许这与WHERE added >= ( CURDATE() - INTERVAL 3 DAY )
23 000 条记录无关
你能告诉我们那个特定表的CREATE TABLE
输出吗?
@Eljakim 在上面更新并包含完整的结构。但请查看速度配置文件 - 似乎复制到 tmp 表是问题。
@FlashThunder 我已经将其更改为 WHERE added >= 21-03-2021 并且没有任何改进。
【参考方案1】:
解决方案
通过为count
添加索引,我将时间缩短了 95% 以上!!!
现在整个操作大约需要 1-1.5 毫秒。
copy_to_temp table
从 10 毫秒减少到 0.5 毫秒 - 仍然使用 65% 的时间,但速度足以满足我的需求。
【讨论】:
【参考方案2】:用于三天前的日期:
SELECT distinct search_item
FROM `tb_search t`
WHERE t.date >= DATE_ADD(CURDATE(), INTERVAL -3 DAY);
或者你可以使用:
SELECT distinct search_item
FROM `tb_search t`
WHERE t.date >= ( CURDATE() - INTERVAL 3 DAY );
【讨论】:
我需要20个最受欢迎的搜索项以上是关于MYSQL 查询慢 SELECT DISTINCT的主要内容,如果未能解决你的问题,请参考以下文章
MySQL,在执行 SELECT DISTINCT 查询之前合并 2 个或更多表?
如何在 python 代码中添加 mysql 查询 select distinct?
mysql查询:SELECT DISTINCT column1,GROUP BY column2
php查询mysql时,报超出内存错误(select count(distinct))时
mysql 去除重复 Select中DISTINCT关键字的用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留
MySQL查询关键字之select/where/group by/having/distinct/order by/limit/regexp/like