【问题标题】:How To Apply Indexing this Query如何应用索引此查询
【发布时间】:2017-05-25 05:40:10
【问题描述】:
SELECT  user_id,username,full_name,display_name,profile_pic,email,
        fb_id,image1,image2,image3,image4,image5,default_pic,
        street_address,locality,country,state,is_verified,is_online,
        city,image6,image7,image8,image9,image10,last_login,
        IFNULL( (
                SELECT  STATUS
                    FROM  vidioo_contacts
                    WHERE  (contact_id = '55000'
                              AND  user_id = vu.user_id
                          )
                      OR  (contact_id = vu.user_id
                              AND  user_id = '55000')),0) AS STATUS,
        (3959 * ACOS( COS(RADIANS(0)) * COS(RADIANS(latitude)) * 
           COS(RADIANS(longitude) - RADIANS(0)) + SIN(RADIANS(0)) *
           SIN(RADIANS(latitude)))
           ) AS distance
    FROM  vidioo_users vu
    WHERE  user_id != '55000'
      AND  gender LIKE 
        ( SELECT  CASE WHEN show_me = 'everyone'
                     THEN '%'
                     ELSE IF(LENGTH(show_me) < 1, '%', show_me)
                  END
            FROM  vidioo_users
            WHERE  user_id = '55000'
            LIMIT  1 
        )
      AND  IFNULL(vu.is_deleted,0) != 55000
      AND  vu.user_id NOT IN (
        SELECT  DISTINCT contact_id
            FROM  vidioo_blocked_users
            WHERE  bloked_by_user = 55000
                          )
      AND  DATEDIFF(NOW(),last_login) < 7
    ORDER BY  last_login DESC
    LIMIT  0,20

我希望对此查询应用索引。

【问题讨论】:

  • 首先,规范你的设计

标签: php mysql indexing


【解决方案1】:

如果表有一个多列索引,那么 mysql 使用索引的最左前缀。例如,您有以下选择查询 -

`SELECT * FROM tbl_name WHERE col1=val1; SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

SELECT * FROM tbl_name WHERE col2=val2; SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;`

如果 (col1, col2, col3) 上存在索引,则只有前两个查询使用该索引。第三个和第四个查询确实涉及到索引列,但是 (col2) 和 (col2, col3) 不是 (col1, col2, col3) 的最左边的前缀。

在您的情况下,您必须创建 3 个索引作为

  1. Index_1(user_id、gender、last_login)
  2. Index_2(user_id)
  3. Index_3(bloked_by_user)

注意:- 索引过多会减慢 INSERT 查询处理。 更多详情Click here

【讨论】:

    【解决方案2】:

    除其他建议外,将AND DATEDIFF(NOW(),last_login) &lt; 7改为

    last_login > NOW() - INTERVAL 7 DAY
    

    您将列 last_login 隐藏在函数 (DATEDIFF) 中,使其无法用于索引。然后,也添加

    INDEX(last_login)
    

    (它可能没有帮助,但它可能。)

    还有,改变

    AND  vu.user_id NOT IN (
        SELECT  DISTINCT contact_id
            FROM  vidioo_blocked_users
            WHERE  bloked_by_user = 55000
                          )
    

    AND NOT EXISTS( SELECT * FROM vidioo_blocked_users
            WHERE  bloked_by_user = 55000
              AND  contact_id = vu.user_id )
    

    一起

    INDEX(bloked_by_user, contact_id) -- in either order
    

    【讨论】:

      【解决方案3】:

      尝试在这四个表列上添加索引,应该会有所帮助:

      contact_id,
      user_id,
      is_deleted,
      last_login.
      

      【讨论】:

        猜你喜欢
        • 2016-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-21
        • 1970-01-01
        • 2012-07-03
        • 1970-01-01
        相关资源
        最近更新 更多