Mysql 使用group by、where和'优化单个表上的查询;旗帜';

Mysql 使用group by、where和'优化单个表上的查询;旗帜';,mysql,sql,performance,Mysql,Sql,Performance,我正在为我反复使用的查询类型的性能而挣扎。任何帮助都将不胜感激 我有下表: item week type flag value 1 1 5 0 0.93 1 1 12 1 0.58 1 1 12 0 0.92 1 2 6 0 0.47 1 2 5 0 0.71 1 2

我正在为我反复使用的查询类型的性能而挣扎。任何帮助都将不胜感激

我有下表:

    item week type  flag   value
    1    1    5     0      0.93 
    1    1    12    1      0.58 
    1    1    12    0      0.92 
    1    2    6     0      0.47 
    1    2    5     0      0.71 
    1    2    5     1      0.22
    ...  ...  ...   ...    ...
(完整的表格有大约10k个不同的项目,200周,1k个类型。标记为0或1。总共约20M行)

我想优化以下查询:

    select item, week, 
    sum(value) as total_value,
    sum(value * (1-least(flag, 1))) as unflagged_value
    from test_table 
    where type in (5,10,14,22,114,116,121,123,124,2358,2363,2381) 
    group by item, week;
目前,我能得到的最快的索引是(type,item,week)和engine=MyIsam。 (我在标准桌面上使用mysql)


您有什么建议(索引、重新编制等)?

我认为您应该在表中只列出两个索引

1. An index on type (non clustered)
2. A composite index on (item, week) in the same order (non clustered)

我认为表中应该只有两个索引

1. An index on type (non clustered)
2. A composite index on (item, week) in the same order (non clustered)

据我所知,只有使用

在您的表格上添加以下
覆盖索引
,并使用
解释检查:

ALTER TABLE test_table  ADD KEY ix1 (type, item, week, value, flag);
SELECT type, item, week,
    SUM(value) AS total_value,
    SUM(IF(flag = 1, value, 0)) AS unflagged_value
FROM test_table
WHERE type IN(5,10,14,22,114,116,121,123,124,2358,2363,2381)
GROUP BY type, item, week;
添加索引后,检查以下带有
解释的查询:

ALTER TABLE test_table  ADD KEY ix1 (type, item, week, value, flag);
SELECT type, item, week,
    SUM(value) AS total_value,
    SUM(IF(flag = 1, value, 0)) AS unflagged_value
FROM test_table
WHERE type IN(5,10,14,22,114,116,121,123,124,2358,2363,2381)
GROUP BY type, item, week;
您可能需要如下方式修改查询:

SELECT item, week,
       SUM(total_value) AS total_value,
       SUM(unflagged_value) AS unflagged_value
FROM(
    SELECT type, item, week,
        SUM(value) AS total_value,
        SUM(IF(flag = 1, value, 0)) AS unflagged_value
    FROM test_table
    GROUP BY type, item, week
)a
WHERE type IN(5,10,14,22,114,116,121,123,124,2358,2363,2381)
GROUP BY item, week;

请参阅查询执行计划

据我所知,只有使用

在您的表格上添加以下
覆盖索引
,并使用
解释检查:

ALTER TABLE test_table  ADD KEY ix1 (type, item, week, value, flag);
SELECT type, item, week,
    SUM(value) AS total_value,
    SUM(IF(flag = 1, value, 0)) AS unflagged_value
FROM test_table
WHERE type IN(5,10,14,22,114,116,121,123,124,2358,2363,2381)
GROUP BY type, item, week;
添加索引后,检查以下带有
解释的查询:

ALTER TABLE test_table  ADD KEY ix1 (type, item, week, value, flag);
SELECT type, item, week,
    SUM(value) AS total_value,
    SUM(IF(flag = 1, value, 0)) AS unflagged_value
FROM test_table
WHERE type IN(5,10,14,22,114,116,121,123,124,2358,2363,2381)
GROUP BY type, item, week;
您可能需要如下方式修改查询:

SELECT item, week,
       SUM(total_value) AS total_value,
       SUM(unflagged_value) AS unflagged_value
FROM(
    SELECT type, item, week,
        SUM(value) AS total_value,
        SUM(IF(flag = 1, value, 0)) AS unflagged_value
    FROM test_table
    GROUP BY type, item, week
)a
WHERE type IN(5,10,14,22,114,116,121,123,124,2358,2363,2381)
GROUP BY item, week;

请参阅查询执行计划

您想用
总和(值*(1-最小值(标志,1))做什么?
最不必要吗?同意波迪卢斯卡。。。如果flag只有0和1个值,那么value*(1-flag)应该在flag为0时执行值求和的技巧您试图用
sum(value*(1-least(flag,1)))做什么?
最不必要吗?同意波迪卢斯卡。。。如果flag只有0和1个值,那么value*(1-flag)应该在flag为0时执行求和的技巧。我不知道覆盖索引的概念。我让它快得惊人!!谢谢你提到的第一个问题比我原来的问题还要快。您的第二个查询速度很慢(关于我的数据)。不客气!第一次查询会更快,因为EXPLAIN`说
使用WHERE,使用INDEX
。我认为第一个查询可能没有正确使用索引,因为在
子句中有
,这就是为什么还要发布替代查询的原因。@cafe876:也可以尝试这个索引:
(项、周、类型、值、标志)
我不知道
覆盖索引的概念。我让它快得惊人!!谢谢你提到的第一个问题比我原来的问题还要快。您的第二个查询速度很慢(关于我的数据)。不客气!第一次查询会更快,因为EXPLAIN`说
使用WHERE,使用INDEX
。我认为第一个查询可能无法正确使用索引,因为在
子句中有
,这就是为什么也发布了备用查询。@cafe876:也可以尝试此索引:
(项、周、类型、值、标志)