V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
banxi1988
V2EX  ›  MySQL

这种两个where_in的SQL可以优化吗?

  •  
  •   banxi1988 ·
    banxi1988 · 2013-06-14 22:50:03 +08:00 · 3598 次点击
    这是一个创建于 4164 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有一个表person,至少有name,memo字段。
    === ===
    name memo
    === ===
    名字1 说明1
    名字2 说明2
    名字3 说明2
    名字4 说明2
    ==== =====

    names = ['名字1','名字2']
    memos = ['说明3','说明3']

    显然names和memos是在程序中构造的。

    SELECT *
    FROM person
    WHERE name in names AND memo in memos;

    但是听说据说where_in的效率不高,更何况这种两个in的。
    (为什么in子句的效率不高?)
    4 条回复    1970-01-01 08:00:00 +08:00
    ipconfiger
        1
    ipconfiger  
       2013-06-14 23:11:12 +08:00   ❤️ 2
    MySql下in查詢會導致索引丟失,然後就變成了全表掃描,如果表大,那麼就鐵定了很慢。
    in 子查詢的情況貌似可以match索引,但是你這裏兩個,鐵定了丟了。

    如果in的內容不是很多的話,可以用union 來代替in。
    優化sql最大的技巧就是 點一點右邊的感謝按鈕 ^_^
    VYSE
        2
    VYSE  
       2013-06-15 02:39:58 +08:00   ❤️ 1
    你可以EXPLAIN看下有没有使用INDEX,现在的QUERY OPTIMIZER已经很智能去处理是否使用INDEX(有时一遍扫表效率更高)。
    见官方文档:
    Each table index is queried, and the best index is used unless the optimizer believes that it is more efficient to use a table scan. At one time, a scan was used based on whether the best index spanned more than 30% of the table, but a fixed percentage no longer determines the choice between using an index or a scan. The optimizer now is more complex and bases its estimate on additional factors such as table size, number of rows, and I/O block size.

    如果一定要使用INDEX,在TABLE后面加上FORCE INDEX (names_index,memos_index)。
    你这种情况相信MYSQL比盲目优化来的好,EXPLAIN还能参考语句效率。
    另可试试拆成俩进行JOIN取代AND看看时间
    banxi1988
        3
    banxi1988  
    OP
       2013-06-15 11:07:42 +08:00
    @ipconfiger mysql下的子查询的in其实会优化成exists子句,不会丢失索引。
    in的内容不多,平均10来条。union使用请明示。谢谢。
    2269195609
        4
    2269195609  
       2013-06-15 13:04:07 +08:00
    若用等值连接查询呢,将后面两个列表组合成表,
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2845 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 11:31 · PVG 19:31 · LAX 03:31 · JFK 06:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.