MySQL - 查询IN子句执行得很糟糕

时间:2018-03-23 12:45:56

标签: mysql performance entity-attribute-value

我有一个包含四个表(项目,属性,快照和值)的MySQL数据库。基本上,表包含给定特定日期(快照)的的某个属性的值。

enter image description here

包含以下列

  • value_id
  • FK_itemid(项目的外键)
  • FK_propertyid(属性的外键)
  • FK_snapshotid(快照的外键)
  • value(as string)

现在我想为其他属性具有特定值的所有项目获取某个属性(-id)的值:

SELECT * FROM
            (SELECT * FROM remian.remian_propertyvalue WHERE 
                                            FK_ItemId IN (SELECT FK_ItemId FROM (SELECT * FROM remian.remian_propertyvalue WHERE FK_PropertyId=1) AS trackerentries WHERE trackerentries.Value IN (12,11) AND
                                            FK_ItemId IN (SELECT FK_ItemId FROM (SELECT * FROM remian.remian_propertyvalue WHERE FK_PropertyId=12) AS statustable WHERE statustable.Value NOT IN ("Rejected","Closed")) AND
                                            FK_ItemId IN (SELECT FK_ItemId FROM (SELECT * FROM remian.remian_propertyvalue WHERE FK_PropertyId=2) AS projectentries WHERE projectentries.Value IN (73,74)))) AS queried
WHERE queried.FK_PropertyId=12 AND FK_SnapshotId = 1;

此查询确实有效但速度很慢(5000个条目为80秒)。有没有更有效的方法来做到这一点?

1 个答案:

答案 0 :(得分:0)

EAV模式非常混乱。使用IN ( SELECT ... )会使情况更糟且更慢

您需要尝试在没有子查询的情况下执行此操作,只需JOINs,例如

SELECT *
    FROM remian_propertyvalue AS a
    JOIN remian_propertyvalue AS b  USING(FK_ItemId)
    JOIN remian_propertyvalue AS c  USING(FK_ItemId)
    WHERE a.FK_PropertyId = 1  AND a.value IN (12,11)
      AND b.FK_PropertyId = 12 AND b.value IN ("Rejected","Closed")
      AND c.FK_PropertyId = 2  AND c.value IN (73,74)
      AND a.FK_PropertyId = 12 AND a.FK_SnapshotId = 1;

此外,“属性”表上没有AUTO_INCREMENT。取而代之的是

PRIMARY KEY(itemId, propertyId),
INDEX(propertyId, value)

这些索引可能存在问题;我真的需要SHOW CREATE TABLE来帮忙。

更多: