0

随着数据库的增长,我的数据库的特定部分出现了性能问题。我有一张类似的桌子:

itemID | name   | value
2      | action | throw
1      | thing  | ball
3      | looks  | dumb
2      | thing  | stick
3      | thing  | rock
1      | action | hit
4      | looks  | grey
1      | action | wedge
3      | action | throw

我需要在此表中查询与具有一个或多个名称 (AND) 和一个或一个或多个值 (OR) 的多个名称匹配的项目 ID。迄今为止,我已经通过 OR 完成了这项工作:

SELECT t1.id FROM features as t1
    LEFT JOIN features as t2 on t1.id = t2.id
WHERE
(
     (t1.`name` = 'thing' AND t1.`value` LIKE 'ball') 
  OR (t1.`name` = 'thing' AND t1.`value` LIKE 'stick')
) 
AND
(
        t2.`name` = 'action' 
   AND (t2.`value` LIKE 'hit' OR t2.`value` LIKE 'thro%')
)

*请注意,在此示例中,每个名称都有 2 个值,但可以有任何数字。如果它有助于澄清,我有这个 sqlFiddle 。

这在一段时间内工作得很好,但随着系统的发展,这些表变得很大(有时超过 400 万行),而且更成问题的是,在它们上运行的查询必须包含许多名称/值集。第 4 次 JOIN 后性能急剧下降,到第 9 次执行查询可能需要一分钟多的时间。我还遇到了查询在 STATISTICS 步骤中冻结了几个小时的问题,我通过将优化器深度设置为 1 来解决这些问题,但这并不理想。

在没有这么多连接的情况下如何执行此查询?

编辑:当我提出问题时,我错过了一个要求(星期一的情况)。值列中的查询值需要不区分大小写,并且可以使用通配符。我已经相应地编辑了我的查询示例。

4

1 回答 1

1

这样的事情怎么样

SELECT id 
FROM features f
group by name
having sum(name = 'thing' and value in ('ball', 'stick')) > 0
or sum(name = 'action' and value in ('hit', 'throw')) > 0

SQLFiddle 演示

于 2013-09-09T17:26:50.727 回答