代码之家  ›  专栏  ›  技术社区  ›  viraptor

优化一个简单的mysql查询以消除文件排序

  •  1
  • viraptor  · 技术社区  · 14 年前

    我有一个服务器不喜欢的简单MySQL查询:

    SELECT zone_id, SUM(inc_sec) AS voucher_used
      FROM cdr_bill_2010_09
     WHERE cust_id = 1234 AND voucher_id = 'XXXXXX'
     GROUP BY zone_id
    

    现在应该很快(通常是这样),因为在客户ID和凭证ID(选择凭证ID)上都有索引。但是它仍然使用帮助器表。解释后:

               id: 1
      select_type: SIMPLE
            table: cdr_bill_2010_09
             type: ref
    possible_keys: cust_id,voucher_id
              key: voucher_id
          key_len: 9
              ref: const
             rows: 1
            Extra: Using where; Using temporary; Using filesort
    

    我能做些具体的事情来摆脱这些吗?我运行的是Debian的5.0.45。

    5 回复  |  直到 11 年前
        1
  •  2
  •   msurovcak    14 年前

    只需尝试添加另一个索引(根据 http://forums.mysql.com/read.php?115,57443,59562 ):

    CREATE INDEX index_zi ON cdr_bill_2010_09 (zone_id,inc_sec); 
    
        2
  •  0
  •   John Boker    14 年前

    您正在为凭证中的所有字节编制索引吗?

    http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html :

    只为列的前缀编制索引 在ORDER BY子句中命名。在这个里面 case,索引不能用于 完全解析排序顺序。为了 例如,如果您有一个字符(20) 列,但只索引前10个 字节,索引无法区分 超过第10个字节的值和 需要文件排序。

    我知道这不是逐条订购,但可能是同一笔交易?

        3
  •  0
  •   Rob Di Marco    14 年前

    您是否尝试创建同时包含客户ID和供应商ID的索引?

    create index idx_cdr_bill_2010_09_joint on cdr_bill_2010_09(cust_id, vendor_id)
    
        4
  •  0
  •   viraptor    14 年前

    实际答案与其他答案很接近。使用“where”键添加索引 (voucher_id) (cust_id) 和“组”键 (zone_id) 解决了问题。事实上 zone_id 它本身就足以消除额外的临时/文件排序,但需要添加另一个临时/文件排序才能加快基本查询的速度。

        5
  •  0
  •   Noushad    11 年前

    在cdr_bill_2010_09上创建索引idx_cdrbill_cust_vouch_zone(cust_id, 凭证ID、区域ID);