有可能提高此SQL查询的性能吗?

prgrmnerd

我有一个具有超过100,000,000行的表,并且我有一个查询,如下所示:

SELECT
    COUNT(IF(created_at >= '2015-07-01 00:00:00', 1, null)) AS 'monthly',
    COUNT(IF(created_at >= '2015-07-26 00:00:00', 1, null)) AS 'weekly',
    COUNT(IF(created_at >= '2015-06-30 07:57:56', 1, null)) AS '30day',
    COUNT(IF(created_at >= '2015-07-29 17:03:44', 1, null)) AS 'recent'
FROM
    items
WHERE
    user_id = 123456;

该表如下所示:

CREATE TABLE `items` (
   `user_id` int(11) NOT NULL,
   `item_id` int(11) NOT NULL,
   `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
    PRIMARY KEY (`user_id`,`item_id`),
    KEY `user_id` (`user_id`,`created_at`),
    KEY `created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

解释看起来相当无害,减去了大量的行数:

1   SIMPLE  items   ref PRIMARY,user_id user_id 4   const   559864  Using index

我使用查询来收集特定用户在4个时间段内的计数。是否有一种更聪明/更快的方法来获取相同的数据,或者我是将新行放入此表中时对这些数据进行计数的唯一选择吗?

费氏菌

我会在created_at字段上添加索引:

ALTER TABLE items ADD INDEX idx_created_at (created_at)

或(按照托马斯的建议),因为您还要过滤user_id的created_at和user_id上的复合索引:

ALTER TABLE items ADD INDEX idx_user_created_at (user_id, created_at)

然后将您的查询写为:

SELECT 'monthly' as description, COUNT(*) AS cnt FROM items
WHERE created_at >= '2015-07-01 00:00:00' AND user_id = 123456

UNION ALL

SELECT 'weekly' as description, COUNT(*) AS cnt FROM items
WHERE created_at >= '2015-07-26 00:00:00' AND user_id = 123456

UNION ALL

SELECT '30day' as description, COUNT(*) AS cnt FROM items
WHERE created_at >= '2015-06-30 07:57:56' AND user_id = 123456

UNION ALL

SELECT 'recent' as description, COUNT(*) AS cnt FROM items
WHERE created_at >= '2015-07-29 17:03:44' AND user_id = 123456

是的,输出有些不同。或者,您可以使用内联查询:

SELECT
  (SELECT COUNT(*) FROM items WHERE created_at>=... AND user_id=...) AS 'monthly',
  (SELECT COUNT(*) FROM items WHERE created_at>=... AND user_id=...) AS 'weekly',
  ...

如果需要平均值,则可以使用子查询:

SELECT
  monthly,
  weekly,
  monthly / total,
  weekly / total
FROM (
  SELECT
    (SELECT COUNT(*) FROM items WHERE created_at>=... AND user_id=...) AS 'monthly',
    (SELECT COUNT(*) FROM items WHERE created_at>=... AND user_id=...) AS 'weekly',
    ...,
    (SELECT COUNT(*) FROM items WHERE user_id=...) AS total
) s

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何提高此SQL Server查询的性能?

来自分类Dev

如何提高此查询的性能

来自分类Dev

提高 SQL 查询性能

来自分类Dev

如何提高sql查询的性能

来自分类Dev

提高此查询的扁平化性能

来自分类Dev

如何提高此视图/查询的性能?

来自分类Dev

有什么方法可以提高JS中此for循环的性能吗?

来自分类Dev

通过 SQL Server 提高 SQL 查询的性能

来自分类Dev

SQL子查询性能需要提高

来自分类Dev

如何提高SQL Server Select查询的性能?

来自分类Dev

如何提高SQL Server Select查询的性能?

来自分类Dev

如何提高SQL Azure查询性能

来自分类Dev

通过使用排序提高sql查询性能?

来自分类Dev

如何提高这个 sql 查询的性能?

来自分类Dev

提高 PHP 文件中的 SQL 查询性能

来自分类Dev

提高 SQL 查询选择性能

来自分类Dev

提高sql join count查询的性能

来自分类Dev

SQL Server:如何提高WHERE子句中具有多个CTE和子查询的查询的性能

来自分类Dev

可以添加带有月份标识符的列来提高查询性能吗?

来自分类Dev

我可以提高此Python代码的性能吗?

来自分类Dev

提高(查询)性能

来自分类Dev

提高LINQ查询性能?

来自分类Dev

提高SimpleMembership查询性能?

来自分类Dev

无法提高查询性能

来自分类Dev

提高查询性能

来自分类Dev

提高查询性能

来自分类Dev

提高子查询的性能

来自分类Dev

提高查询性能

来自分类Dev

可以优化此查询以提高网站速度吗?