Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何利用3GB表优化Mysql选择_Mysql_Sql_Performance_Query Optimization - Fatal编程技术网

如何利用3GB表优化Mysql选择

如何利用3GB表优化Mysql选择,mysql,sql,performance,query-optimization,Mysql,Sql,Performance,Query Optimization,我有一个包含37000000行和3gb数据的表 CREATE TABLE `stats_raw` ( `user_id` INT(11) NOT NULL, `date` DATETIME(6) NOT NULL, `ip` VARBINARY(16) NULL DEFAULT NULL, INDEX `stats_raw_user_id_index` (`user_id`), INDEX `stats_raw_date_index` (`date`),

我有一个包含37000000行和3gb数据的表

CREATE TABLE `stats_raw` (
    `user_id` INT(11) NOT NULL,
    `date` DATETIME(6) NOT NULL,
    `ip` VARBINARY(16) NULL DEFAULT NULL,
    INDEX `stats_raw_user_id_index` (`user_id`),
    INDEX `stats_raw_date_index` (`date`),
    INDEX `stats_raw_user_id_data_index` (`user_id`, `date`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
当我尝试执行以下查询时(由laravel生成,这就是它看起来很奇怪的原因):

返回结果大约需要40秒


我如何在mysql上优化它

首先,我将把查询写为:

select count(ip) as total, INET6_NTOA(ip) as ip
from `stats_raw`
where `user_id` = 1 and `date` >= '2019-02-10'
group by `ip`
order by `total` desc
limit 10;
其次,您需要一个关于
stats\u raw(用户id、日期、ip)
的索引


也就是说,目前尚不清楚有多少数据正在被处理。我认为没有一种方法可以绕过对
分组依据
排序依据
的排序,因此如果您有大量数据,您可能无法加快此查询的速度,而无需付出更大的努力(例如使用触发器维护摘要表)。

Gordon确实将其与查询结合在一起,因此,我的回答假设您将使用他的查询

您可以尝试的一个小改进是将
date
列数据类型更改为
date
,而不是
DATETIME
(假设您实际上不需要时间部分)

通过这样做,您可以减少开销,这将允许一次加载更多数据,从而减少一些开销


当然,如果您需要其他事情的时间部分,那么这不是一个选项。

使用物化视图?嗨@RedaMeskali,我第一次听说它时,很容易做到?是的,您可以在这里阅读它们:。感谢Gordon,我更新了总行数,我在写问题时添加了xxx占位符,但忘记了更新它。将检查您的建议并更新您的建议后,查询时间缩短到15秒,这是一个很大的改进。我会等着看我是否得到任何其他答案并奖励你。再次感谢您只需做
COUNT(*)
,而不是
COUNT(ip)
。嗨@RickJames尝试过,但我在几秒钟内看不到有什么不同。谢谢,然后建议用户使用更小的
INT
。并使其
无符号
。并且去掉
stats\u raw\u user\u id\u index
select count(ip) as total, INET6_NTOA(ip) as ip
from `stats_raw`
where `user_id` = 1 and `date` >= '2019-02-10'
group by `ip`
order by `total` desc
limit 10;