mysql - 提高多主表的查询性能

标签 mysql sql sql-tuning

我有一个问题。我已经为所有连接的键创建索引,预过滤主表并选择特定的行来选择,但它仍然需要很长时间才能显示(有时会挂起)。我们应该怎么做才能提高性能?

SELECT *
FROM   t_responden a
       INNER JOIN t_kepemilikan_tik b
               ON a.res_id = b.res_id
       INNER JOIN t_televisi c
               ON a.res_id = c.res_id
       INNER JOIN t_telepon_hp d
               ON a.res_id = d.res_id
       INNER JOIN t_radio e
               ON a.res_id = e.res_id
       INNER JOIN t_media_cetak f
               ON a.res_id = f.res_id
       INNER JOIN t_internet g
               ON a.res_id = g.res_id
       LEFT JOIN t_mst_pendidikan n
              ON a.res_pendidikan_kk = n.kd_pendidikan
       LEFT JOIN t_mst_pendidikan o
              ON a.res_pendidikan = o.kd_pendidikan
       LEFT JOIN t_mst_penghasilan p
              ON a.res_penghasilan = p.kd_penghasilan

       LEFT JOIN t_mst_aksesibilitas q
              ON a.res_aksesibilitas = q.kd_akses
       LEFT JOIN t_mst_mobilitas r
              ON a.res_mobilitas = r.kd_mobilitas
       LEFT JOIN t_mst_pekerjaan s
              ON a.res_pekerjaan = s.kode
       LEFT JOIN t_mst_pengeluaran t
              ON a.res_pengeluaran = t.kode

       INNER JOIN t_pernyataan h
               ON a.res_id = h.res_id

       INNER JOIN (SELECT * FROM t_mst_prop WHERE kode IN ( '3200', '1600', '1800', '3600' )) i
               ON a.res_propinsi = i.kode

       INNER JOIN (SELECT * FROM t_mst_kabkota WHERE kode_prop IN ( '3200', '1600', '1800', '3600' )) j
               ON ( a.res_kabkota = j.kode
                    AND a.res_propinsi = j.kode_prop )

       INNER JOIN (SELECT * FROM t_mst_kec WHERE kode_prop IN ( '3200', '1600', '1800', '3600' )) k
               ON ( a.res_kecamatan = k.kode
                    AND a.res_kabkota = k.kode_kabkota
                    AND a.res_propinsi = k.kode_prop )

       INNER JOIN (SELECT * FROM t_mst_desa WHERE kode_prop IN ( '3200', '1600', '1800', '3600' ))l
               ON ( a.res_keldesa = l.kode
                    AND a.res_kabkota = l.kode_kabkota
                    AND a.res_propinsi = l.kode_prop
                    AND l.kode_kec = a.res_kecamatan )

WHERE  a.res_tahunsurvei = 2013
       AND res_propinsi IN ( '3200', '1600', '1800', '3600' )
ORDER  BY 1

最佳答案

SELECT STRAIGHT_JOIN
      *
   FROM   
      t_responden a
         INNER JOIN t_kepemilikan_tik b
            ON a.res_id = b.res_id
         INNER JOIN t_televisi c
            ON a.res_id = c.res_id
         INNER JOIN t_telepon_hp d
            ON a.res_id = d.res_id
         INNER JOIN t_radio e
            ON a.res_id = e.res_id
         INNER JOIN t_media_cetak f
            ON a.res_id = f.res_id
         INNER JOIN t_internet g
            ON a.res_id = g.res_id
         LEFT JOIN t_mst_pendidikan n
            ON a.res_pendidikan_kk = n.kd_pendidikan
         LEFT JOIN t_mst_pendidikan o
            ON a.res_pendidikan = o.kd_pendidikan
         LEFT JOIN t_mst_penghasilan p
            ON a.res_penghasilan = p.kd_penghasilan
         LEFT JOIN t_mst_aksesibilitas q
            ON a.res_aksesibilitas = q.kd_akses
         LEFT JOIN t_mst_mobilitas r
            ON a.res_mobilitas = r.kd_mobilitas
         LEFT JOIN t_mst_pekerjaan s
            ON a.res_pekerjaan = s.kode
         LEFT JOIN t_mst_pengeluaran t
            ON a.res_pengeluaran = t.kode
         INNER JOIN t_pernyataan h
            ON a.res_id = h.res_id

         INNER JOIN t_mst_prop i
            ON a.res_propinsi = i.kode
         INNER JOIN t_mst_kabkota j
               ON  a.res_propinsi = j.kode_prop 
               AND a.res_kabkota = j.kode
         INNER JOIN t_mst_kec k
               ON a.res_propinsi = k.kode_prop
               AND a.res_kecamatan = k.kode
               AND a.res_kabkota = k.kode_kabkota
         INNER JOIN t_mst_desa l
               ON  a.res_propinsi = l.kode_prop
               AND a.res_keldesa = l.kode
               AND a.res_kabkota = l.kode_kabkota
               AND a.res_kecamatan = l.kode_kec
   WHERE  
          a.res_tahunsurvei = 2013
      AND a.res_propinsi IN ( '3200', '1600', '1800', '3600' )
   ORDER BY 
      1

您的 t_responden 表应该有一个索引 ON ( res_tahunsurvei, res_propinsi) 以匹配您的 where 资格标准。此外,您通过子选择应用 IN 到其他表的所有内部连接都在杀死您。您已经限制了 where 中的“kode”,所以如果您将其应用为您的加入,您应该会很好。

此外,由于所有其他表看起来更“查找”,我添加了“STRAIGHT_JOIN”来告诉 MySQL 按照您列出的表的顺序查询

关于mysql - 提高多主表的查询性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17332766/

相关文章:

sql - 性能调整或替代 distinct 子句

android - openfire可以和mysql服务器合并吗

mysql - PHP mysql 连接表返回所有结果

sql - 使用 T-SQL 插入 n 条记录

sql - MySQL 复合索引和运算符 BETWEEN

mysql - 请帮我优化这个 MySQL SELECT 语句

Mysql慢查询日志每5秒记录一次相同的查询

php - 为什么 "SHOW TABLES"不工作

php - 使用 case 语句编写子查询

sql - 在Oracle中创建表产生 "Missing right parenthesis"错误