跨多个行匹配,没有很多连接

时间:2013-09-09 17:14:10

标签: mysql

我的数据库中存在性能问题,因为它已经增长了。我有一张类似的表:

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)的更多名称onw匹配的项目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个值,但可以有任何数字。 如果它有助于澄清,我有this sqlFiddle

这种方法运行良好一段时间,但随着系统的发展,这些表变得越来越大(有时超过400万行),而且更有问题的是,在它们上运行的查询必须包含许多名称/值集。在第4次JOIN之后性能急剧下降,到9时,执行查询可能需要一分多钟。我也有问题冻结在STATISTICS步骤中数小时,我已经通过将优化器深度设置为1来进行绑定,但这不太理想。

如果没有这么多连接,我该如何执行此查询?

编辑:我在提出问题时错过了其中一项要求(周一的情况)。值列中的查询值需要不区分大小写,并且通配符是可能的。我已相应地编辑了我的查询示例。

1 个答案:

答案 0 :(得分: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 demo