2015-10-14 148 views
1

我有一个非常庞大的MySQL数据库,并且在选择数据时遇到性能问题。让我先解释我在我的项目中做了什么:我有一个文件列表。每个文件都应该用一些工具进行分析。分析结果存储在结果表中。MySql SELECT在巨大的数据库中查询性能问题

我有一个文件(样本)表。该表包含约1000万行。模式如下所示:

idsample|sha256|path|... 

另一个(非常小的表格)是标识该工具的表格。架构:

idtool|name 

第三张桌子将是最大的一张。该表包含我用于分析文件的所有工具结果(行数将是文件数TIMES工具数)。架构:

id|idsample|idtool|result information| ... 

我在找的是一个查询,它返回给定工具ID(尚未存在结果)的UNPROCESSED文件。 (最有效)的方式,我发现,到目前为止,查询这些条目是以下几点:

SELECT 
    s.idsample 
FROM 
    samples AS s 
WHERE 
    s.idsample NOT IN (
     SELECT 
      idsample 
     FROM 
      results 
     WHERE 
      idtool = 1 
    ) 
LIMIT 100 

的问题是,查询越来越慢的结果表越来越大。 您有任何改进建议吗?还有一个问题是,我无法更改表格的结构,因为这是一个共享数据库,也被其他项目使用。 (我认为)改进的唯一方法是找到更有效的选择查询。

非常感谢你, 菲利普

+0

有没有索引? – hjpotter92

+0

如果可以,请在where子句中添加更多约束。特别是嵌套的,因为它首先被评估。您正在使用的where子句确保您已选择好的索引。 idtool会是一个不错的选择。只要它在99%的行中不是1。 – FirebladeDan

+0

所有标识符(idsample,idtool)在所有表中都有一个索引 – Philipp

回答

1

左连接可以表现得更好,特别是如果idsample两个表中被索引;根据我的经验,这些类型的“查询”最好由JOIN提供,而不是那种子查询。

SELECT s.idsample 
FROM samples AS s 
LEFT JOIN results AS r ON s.idsample = r.idsample AND r.idtool = 1 
WHERE r.idsample IS NULL 
LIMIT 100 
; 

另一种更复杂的可能的解决方案是创建与完整的“未处理列表”第四个表,然后用在其他三个表上的触发器来维护它;即

  • 当添加新工具时,将所有当前文件添加到第四个表(使用新工具)。
  • 添加新文件时,将所有当前工具添加到第四个表格(使用新文件)。
  • 当输入新结果时,从第四个表中删除相应的记录。
+0

是的,我也是同样的观点。但是为什么你使用r.idsample IS NULL –

+0

@ rup-不是... – FirebladeDan

+0

@rupesh_padhye'r.idsample IS NULL'将结果过滤为只有''样本“记录没有与'result'表中的idtool = 1'记录相关联的记录。在这种情况下,那个WHERE条件发生在连接之后。 – Uueerdo