如何有效地获取数据并在一次摆动中计算行数?

时间:2015-12-23 02:55:01

标签: mysql sql database performance database-performance

假设您有一张包含数百万条记录的表格 - 让我们将每个记录称为" 项目"。 该表有一些列,包括一个布尔列 - 让我们称之为isProcessed - 还有一个列有工作人员的电子邮件地址 - 让我们称之为{{1 }}

让我们说,工人John Smith(john.smith@example.org)调用一个事件,该事件将返回(1)所有未处理的项目worker = false)一方面又(2)John处理的项目数量

我的第一个想法是简单地做两个查询,一个获取项目,第二个查询计算John处理的所有项目。

但这似乎效率很低,因为我需要在数百万条记录中迭代两次。我也可以遍历每一行并立即检查isProcessedisProcessed列,因此我不会两次运行该表。

在代码性能方面,哪种方法在SQL中更有效?或者更一般地说,建议使用哪种方法?

4 个答案:

答案 0 :(得分:0)

您可以在一个查询中执行此操作:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.ColumnIndex == 1 || e.ColumnIndex == 2)
    {
        if (e.Value != null)
        {
            e.Value = Encoding.UTF8.GetString((byte[]) e.Value);
            e.FormattingApplied = true;
        }
        else
            e.FormattingApplied = false;
    }
}

答案 1 :(得分:0)

我建议添加如下的子句:

[_venues[0] update:^Venue *(NSArray *myScenes, NSError *error) {
    if (error) {
        NSLog(@"Error: %@ %@", error, [error userInfo]);
    }
    else {

        NSLog(@"myObjects are: %@", myScenes);
        _venues[0].scenes = myScenes;


    }
}];

这将有效地计算约翰'是SUM(IF(worker='john', 1, 0)) AS johncount 连续。

答案 2 :(得分:0)

这取决于索引,以及它们是否有用。

一般来说,“flags”(isProcessed)对索引没用,因为它们的“基数”不好。相反,简单地执行表扫描更简单且(通常)更快。因此,INDEX(isProcessed)可能毫无用处。

OTOH,worker='John'可能有用。但如果John处理了四分之一的项目,那就不行了。因此,INDEX(worker)是否有用是可疑的。

如果两个索引都有用,那么这将是加速:

( SELECT 'unprocessed' AS x, COUNT(*) AS ct FROM tbl WHERE isProcessed = false )
UNION ALL
( SELECT 'processed' AS x, COUNT(*) FROM tbl WHERE worker = 'John');

答案 3 :(得分:0)

您可以考虑维护一个包含两列tworker的查找表processed_count,计算每个工作人员的已处理项目数。此表可以通过触发器保持同步,并且包含一行worker = NULL(或一些魔术文本)以保留未处理的项目数。

然后你可以

SELECT processed_count FROM t AS unprocessed WHERE worker IS NULL

SELECT processed_count FROM t AS processed_by_john WHERE worker='john'

这个表格会随着工人的数量呈线性增长,如果你有很多工人,可以编制索引。