Mysql JOIN vs UNION vs IN()-大表和许多WHERE条件

Mysql JOIN vs UNION vs IN()-大表和许多WHERE条件,mysql,sql,Mysql,Sql,我使用MySQL 5.5,创建了3个表用于测试: 属性(实体id、cid、aid、值)-索引:全部 项目(实体id、价格、货币)-索引:实体id 汇率(货币从、货币到、汇率)-指数:无 我需要计算指定条件(按属性搜索)的结果,并选择按某列排序的X行。 查询应支持在项目属性(属性表)中搜索。 首先我有一个这样的问题: SELECT i.entity_id, i.price * COALESCE(r.rate, 1) AS final_price FROM items i JOIN attribu

我使用MySQL 5.5,创建了3个表用于测试:

  • 属性(实体id、cid、aid、值)-索引:全部
  • 项目(实体id、价格、货币)-索引:实体id
  • 汇率(货币从、货币到、汇率)-指数:无
  • 我需要计算指定条件(按属性搜索)的结果,并选择按某列排序的X行。 查询应支持在项目属性(属性表)中搜索。

    首先我有一个这样的问题:

    SELECT i.entity_id, i.price * COALESCE(r.rate, 1) AS final_price 
    FROM items i
    JOIN attributes a ON a.entity_id = i.entity_id
    LEFT JOIN rates r ON i.currency = r.currency_from AND r.currency_to = 'EUR'
    WHERE a.cid = 4 AND ( (a.aid >= 10 AND a.value > 2000) OR (a.aid <= 10 AND a.value > 5) )
    HAVING final_price BETWEEN 0 AND 9000
    ORDER BY final_price DESC
    LIMIT 20
    
    我将COUNT()分组为7(要搜索的属性数),因为我需要查找具有所有这些属性的项目

    解释基本查询(第一个查询):

    我读了很多关于比较
    UNION
    vs
    JOIN
    vs
    IN()
    的主题,最好的结果是第二个选项,但总是太慢

    有没有办法在这里获得更好的性能?为什么这么慢?
    我是否应该考虑将一些逻辑(将此查询拆分为3个小查询)移动到后端(php/ror)代码中?

    我会稍微重新构造您的查询,并首先创建属性表 然后加入到项目中。另外,我会在上有一个覆盖指数 items表通过(实体id、价格)和属性表上的索引 打开(cid、aid、value、entity_id)和您的费率表索引 ON(货币从、货币到、汇率)。这样,所有的索引都覆盖了索引 引擎不需要转到原始数据页来获取数据,它可以 从已用于加入/标准的索引中提取

    SELECT 
          i.entity_id, 
          i.price * COALESCE(r.rate, 1) AS final_price 
       FROM 
          attributes a 
             JOIN items i
                ON a.entity_id = i.entity_id 
             LEFT JOIN rates r 
                ON i.currency = r.currency_from 
                AND r.currency_to = 'EUR'
       WHERE 
          a.cid = 4 AND ( (a.aid >= 10 AND a.value > 2000) OR (a.aid <= 10 AND a.value > 5) )
       HAVING 
          final_price BETWEEN 0 AND 9000
       ORDER BY 
          final_price DESC
       LIMIT 20
    

    您似乎没有用于
    join
    s的列的索引。这就是从优化开始的地方。但是如果你有一个生成大量查询的整个系统,这个问题对于这样的论坛来说可能太大了。我为currency和currency\u添加了索引到/currency\u from,现在是~1.3535。我只有搜索查询。现在需要~0.21。我在问题中添加了更多的条件,请看。@dem,修改后的答案。你的意思是在旧的where语句之外添加额外的in()语句以获得帮助吗?@dem,是的。这样,如果“aid”值为3,它将使(…,…,…,…,…,…)中的“and.id”失败,并且永远不必使用所有的and/or cast值和/或cast值等进入其余部分。。。它马上就失败了,并且不需要满足其余的条件。我要求确认,因为它不会改变执行时间。也许,我会在更大的布景上看到不同,对吗?顺便问一下,为了证明你的话,你知道一些关于解析SQL查询(MySQL)的材料吗?
    id  select_type table   type    possible_keys   key key_len ref rows    Extra   
    1   SIMPLE  a   ALL entity_id,value NULL    NULL    NULL    379999  Using where; Using temporary; Using filesort
    1   SIMPLE  i   eq_ref  PRIMARY PRIMARY 4   testowa.a.entity_id 1   Using where
    1   SIMPLE  r   ALL NULL    NULL    NULL    NULL    2   
    
    SELECT 
          i.entity_id, 
          i.price * COALESCE(r.rate, 1) AS final_price 
       FROM 
          attributes a 
             JOIN items i
                ON a.entity_id = i.entity_id 
             LEFT JOIN rates r 
                ON i.currency = r.currency_from 
                AND r.currency_to = 'EUR'
       WHERE 
          a.cid = 4 AND ( (a.aid >= 10 AND a.value > 2000) OR (a.aid <= 10 AND a.value > 5) )
       HAVING 
          final_price BETWEEN 0 AND 9000
       ORDER BY 
          final_price DESC
       LIMIT 20
    
          a.cid = 4 
       AND a.id in ( 10, 121, 45, 95, 98, 199, 102 )
       AND  ( rest of the complex aid, casting and between criteria )