V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
QQ16748717
V2EX  ›  问与答

1000 多万条数据,我建了索引还是慢,怎么办?

  •  
  •   QQ16748717 · 2015-02-05 12:44:52 +08:00 · 5100 次点击
    这是一个创建于 3605 天前的主题,其中的信息可能已经有所发展或是发生改变。
    create index SelectName on datalist(Name)

    select id,Name from DataType where charindex('数学',Name)>0

    一1000多万条记录 ,运行完以上的居然查了24秒,太久了,有什么能加快的方法么?
    29 条回复    2015-02-06 07:45:45 +08:00
    coldwinds
        1
    coldwinds  
       2015-02-05 12:51:08 +08:00
    你确定用到索引了么
    QQ16748717
        2
    QQ16748717  
    OP
       2015-02-05 12:54:01 +08:00
    @coldwinds 是不是我写错了?我是新手,不是太懂,以上这样写不是已经可以了么?
    denghongcai
        3
    denghongcai  
       2015-02-05 13:01:26 +08:00
    你用了function的情况下索引没有太大意义,用contains会比charindex要快,或者试下LIKE
    QQ16748717
        4
    QQ16748717  
    OP
       2015-02-05 13:02:55 +08:00
    我的表字段 id,name,info
    1 张三 参加了第3学期的24周下等第2节数学课
    2 张工 参加了第3学期的14周下等第3节语文课
    3 张的 参加了第3学期的21周下等第1节数学课

    create index SelectName on datalist(Name)

    select id,Name from DataType where charindex('数学',info)>0

    一1000多万条记录 ,运行完以上SQL代码查所有上数据课的报名统计,我要怎么写才快?
    QQ16748717
        5
    QQ16748717  
    OP
       2015-02-05 13:03:08 +08:00
    @denghongcai 我的表字段 id,name,info
    1 张三 参加了第3学期的24周下等第2节数学课
    2 张工 参加了第3学期的14周下等第3节语文课
    3 张的 参加了第3学期的21周下等第1节数学课

    create index SelectName on datalist(Name)

    select id,Name from DataType where charindex('数学',info)>0

    一1000多万条记录 ,运行完以上SQL代码查所有上数据课的报名统计,我要怎么写才快?
    denghongcai
        6
    denghongcai  
       2015-02-05 13:09:35 +08:00
    你这表名到底是datalist还是DataType

    select id,Name from DataType where info contains "数学"
    QQ16748717
        7
    QQ16748717  
    OP
       2015-02-05 13:15:38 +08:00
    @denghongcai 2个都有,但是 datalist的数据最多
    em70
        8
    em70  
       2015-02-05 13:15:50 +08:00
    这种情况无法使用索引的,info字段做一个全文索引吧,虽然得花比较长时间,但处理完后查询效率就有保证了

    mysql不直接支持中文全文索引,需要先做base64处理.或者自己写个程序遍历一下把学科信息提取放一个独立字段里.
    denghongcai
        9
    denghongcai  
       2015-02-05 13:20:49 +08:00
    如果这种查询是很频繁的,比较好的方法是先遍历一遍当前的数据,把所有课的频次都提取出来。如果需要对数据进行增加或者删除修改,直接改你提取后的数据就好了,相当于做一个专用的cache
    QQ16748717
        10
    QQ16748717  
    OP
       2015-02-05 13:22:09 +08:00
    @em70 我是SQL2008 哭了~怎么办
    tabris17
        11
    tabris17  
       2015-02-05 13:22:49 +08:00
    你需要的是全文检索
    rrfeng
        12
    rrfeng  
       2015-02-05 13:34:03 +08:00
    我怎么觉得 info 需要拆分呢……
    QQ16748717
        13
    QQ16748717  
    OP
       2015-02-05 13:36:52 +08:00
    @rrfeng 拆分?不明白
    lincanbin
        14
    lincanbin  
       2015-02-05 13:38:13 +08:00 via Android
    你这个会全表扫描,索引不是建了就会快的
    siw
        15
    siw  
       2015-02-05 13:44:06 +08:00
    这个ID好像全表扫,

    CREATE NONCLUSTERED SelectName ON datalist(Name)
    INCLUDE (ID);

    试试,
    ETiV
        16
    ETiV  
       2015-02-05 13:56:41 +08:00
    重新设计表结构吧...

    id,name,info
    1 张三 参加了第3学期的24周下等第2节数学课


    id, name, term, week, class, class_name
    1, 张三 3, 24, 2, 数学
    msg7086
        17
    msg7086  
       2015-02-05 14:00:07 +08:00
    首先你先要了解范式。
    所以你先要学习数据库基础知识。

    你这种结构如果要用数据库做快速查询的话,做不到吧。
    别说千万,十万条都够你卡一下了。
    Ransford
        18
    Ransford  
       2015-02-05 14:02:03 +08:00
    分区 or 换数据库
    lbp0200
        19
    lbp0200  
       2015-02-05 14:03:28 +08:00
    不符合数据库设计三范式。
    你是学生吧?在做学校的选课程序?
    iamxi
        20
    iamxi  
       2015-02-05 14:10:55 +08:00
    额,1000万+的数据不多。只是你要对表有点改动而已。不要直接把“第3学期的24周下等第2节数学课”这样的数据放入数据库,改应该改造成 学期、周、当天课程序号、课程名称,学期、周和课程号都应该是数字,至于课程名称新建课程的信息表,把课程的主键放到那张数据表中,比如数学的ID是1,那
    1 张三 参加了第3学期的24周下等第2节数学课
    变成
    1 张三 3 24 2 1

    如果可以,应该有个状态标识参加了还是缺席了,如1参加,缺席
    那数据行就变成 1 张三 1 3 24 2 1
    如果已经有学生的信息表,那张三也应该和学生信息表做关联,使用学生信息表的主键。
    QQ16748717
        21
    QQ16748717  
    OP
       2015-02-05 14:31:27 +08:00
    @ETiV 主要是表是很久很久以前做的了,做这个的老师都转成教授了,现在是我接手,有上千万条数据,很难转呀
    QQ16748717
        22
    QQ16748717  
    OP
       2015-02-05 14:33:09 +08:00
    @msg7086 这个是以前的学校老师做的
    QQ16748717
        23
    QQ16748717  
    OP
       2015-02-05 14:33:30 +08:00
    @lbp0200 我也很为难
    idblife
        24
    idblife  
       2015-02-05 14:59:51 +08:00
    上千万的数据还算多?
    在索引列上使用表达式,索引是不生效的。
    pandada8
        25
    pandada8  
       2015-02-05 15:08:27 +08:00
    向楼上说的改改表结构吧
    能停机的话就写个Python脚本啥的转换下,然后切过去
    youxiachai
        26
    youxiachai  
       2015-02-05 15:10:23 +08:00
    嗯..把硬盘换成 ssd.. 会不会有质的飞跃呢...
    shakoon
        27
    shakoon  
       2015-02-05 15:11:22 +08:00
    这个表的结构建得有问题,重新建一个吧,参照16楼。如果非得用到现在这个结构,再建一个视图把字段拼出来就是了。
    ETiV
        28
    ETiV  
       2015-02-05 15:11:57 +08:00
    看来是个千古大坑...

    如果为了保留兼容性, 建议不去掉 info 字段, 同时像我上面写的, 增加那些字段.

    这样老的程序还可以用, 新的程序查起来也不会太痛苦.
    QQ16748717
        29
    QQ16748717  
    OP
       2015-02-06 07:45:45 +08:00
    @ETiV 只能是按你说的了,真是前人不做好,后人就遭殃了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3495 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 04:51 · PVG 12:51 · LAX 20:51 · JFK 23:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.