免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 8787 | 回复: 23
打印 上一主题 下一主题

大家看看这条SQL还有优化的余地么? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-02 16:15 |只看该作者 |倒序浏览
mysql> desc notice_message;
+-------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra                         |
+-------------+------------------+------+-----+---------+----------------+
| id                   | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| member_id    | int(11) unsigned | NO   | MUL | 0         |                           |
| message       | char(255)            | NO   | MUL |            |                           |
| submit_date  | datetime             | NO   | MUL |            |                           |
+-------------+------------------+------+-----+---------+----------------+

mysql> show index from notice_message;
+----------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table          | Non_unique | Key_name       | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| notice_message |          0 | PRIMARY            |            1 | id                  | A         |     3790729 |     NULL | NULL   |      | BTREE      |         |
| notice_message |          1 | member_id        |            1 | member_id   | A         |     1263576 |     NULL | NULL   |      | BTREE      |         |
| notice_message |          1 | submit_date      |            1 | submit_date | A         |     3790729 |     NULL | NULL   |      | BTREE      |         |
| notice_message |          1 | message           |            1 | message       | A         |     3790729 |       20   | NULL   |      | BTREE      |         |
| notice_message |          1 | submit_date_id |            1 | submit_date | A         |     3790729 |     NULL | NULL   |      | BTREE      |         |
| notice_message |          1 | submit_date_id |            2 | id                  | A         |     3790729 |     NULL | NULL   |      | BTREE      |         |
+----------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

mysql> explain SELECT * FROM `notice_message` WHERE submit_date > '2009-03-05 00:00:00' AND submit_date < '2009-03-06 00:00:00' ORDER BY id DESC LIMIT

0,5000;
+----+-------------+----------------+-------+----------------------------+-------------+---------+------+-------+-----------------------------+
| id   | select_type | table                  | type   | possible_keys                        | key               | key_len  | ref    | rows   | Extra                       |
+----+-------------+----------------+-------+----------------------------+-------------+---------+------+-------+-----------------------------+
|  1   | SIMPLE       | notice_message | range | submit_date,submit_date_id | submit_date | 8            | NULL | 13762 | Using where; Using filesort |
+----+-------------+----------------+-------+----------------------------+-------------+---------+------+-------+-----------------------------+
1 row in set (0.00 sec)
这里为什么用不到 聚合索引 submit_date_id ,使用 use index(submit_date_id) 也用不到的!

以前是
SELECT * FROM `notice_message`  WHERE  submit_date LIKE '2009-03-05%'  ORDER BY id DESC LIMIT 7500,50;
但是 LIKE 根本用不到索引,全表扫描,十几分钟。才换成上面的,但排序还是用不到索引!

论坛徽章:
0
2 [报告]
发表于 2009-04-02 17:09 |只看该作者
凭感觉随便说一句:
索引太多了

评分

参与人数 1可用积分 +2 收起 理由
枫影谁用了 + 2 en

查看全部评分

论坛徽章:
0
3 [报告]
发表于 2009-04-02 17:28 |只看该作者
凭感觉随便说一句:
索引太多了


恩,强制使用聚合索引还是用到文件排序的:
mysql> explain SELECT * FROM `notice_message` use index(submit_date_id ) WHERE submit_date > '2009-03-05 00:00:00' AND submit_date < '2009-03-06 00:00:00' ORDER BY id DESC LIMIT 0,5000;

+----+-------------+----------------+-------+----------------------------+-------------+---------+------+-------+-----------------------------+
| id   | select_type | table                  | type   | possible_keys    | key                   | key_len  | ref    | rows   | Extra                                   |
+----+-------------+----------------+-------+----------------------------+-------------+---------+------+-------+-----------------------------+
|  1   | SIMPLE       | notice_message | range | submit_date_id | submit_date_id | 8            | NULL | 13762 | Using where; Using filesort |
+----+-------------+----------------+-------+----------------------------+-------------+---------+------+-------+-----------------------------+
1 row in set (0.00 sec)

论坛徽章:
0
4 [报告]
发表于 2009-04-02 18:09 |只看该作者
原帖由 simeiren 于 2009-4-2 17:28 发表


恩,强制使用聚合索引还是用到文件排序的:
mysql> explain SELECT * FROM `notice_message` use index(submit_date_id ) WHERE submit_date > '2009-03-05 00:00:00' AND submit_date < '2009-03-06 00:0 ...



说了你这张表的索引建多了

除了PK和PK的内置索引,其它的都删掉吧

[ 本帖最后由 老肥羊 于 2009-4-2 18:11 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-04-03 15:22 |只看该作者
说了你这张表的索引建多了
除了PK和PK的内置索引,其它的都删掉吧


全删掉了
还是有Using filesort
用不用 Using filesort  排序跟索引多少完全没关系!

论坛徽章:
0
6 [报告]
发表于 2009-04-03 15:44 |只看该作者
原帖由 simeiren 于 2009-4-3 15:22 发表


全删掉了
还是有Using filesort
用不用 Using filesort  排序跟索引多少完全没关系!



我也弄了些數據測了測

大概一百萬條吧

按你的SQL

沒有filesort的

不過我用的是innodb

有圖有真相

[ 本帖最后由 老肥羊 于 2009-4-3 15:52 编辑 ]

1.png (13.27 KB, 下载次数: 68)

1.png

2.png (7.86 KB, 下载次数: 60)

2.png

3.png (11.03 KB, 下载次数: 70)

3.png

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
7 [报告]
发表于 2009-04-03 17:02 |只看该作者
去掉limit看看。这些也都证明不了什么。limit 1000,100000结果完全不一样。

mysql> explain select * from aa where showtime > '2009-01-01' and showtime < '2009-03-01'  order by id asc \G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: aa
         type: ALL
possible_keys: showtime
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1505730
        Extra: Using where; Using filesort
1 row in set (0.00 sec)

ERROR:
No query specified

mysql> explain select * from aa where showtime > '2009-01-01' and showtime < '2009-03-01'  order by id asc  limit 10000 \G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: aa
         type: index
possible_keys: showtime
          key: id
      key_len: 8
          ref: NULL
         rows: 23492
        Extra: Using where
1 row in set (0.01 sec)

ERROR:
No query specified

[ 本帖最后由 枫影谁用了 于 2009-4-3 17:06 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2009-04-03 17:07 |只看该作者
原帖由 枫影谁用了 于 2009-4-3 17:02 发表
去掉limit看看。这些也都证明不了什么。limit 1000,100000结果完全不一样。




有圖有真相

4.png (4.02 KB, 下载次数: 72)

4.png

5.png (12.22 KB, 下载次数: 77)

5.png

论坛徽章:
1
白银圣斗士
日期:2015-11-23 08:33:04
9 [报告]
发表于 2009-04-03 17:10 |只看该作者
原帖由 老肥羊 于 2009-4-3 17:07 发表



有圖有真相

晕。。你跟我证明什么

论坛徽章:
0
10 [报告]
发表于 2009-04-03 17:20 |只看该作者
原帖由 枫影谁用了 于 2009-4-3 17:10 发表

晕。。你跟我证明什么



看你上上貼懷疑limit麼
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP