`
lenxen
  • 浏览: 30577 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

常见的一些MySQL数据库优化技巧

阅读更多

mysql优化和性能很重要,特别是对一些中等站,简单的优化效果明显

    下是是个人对网站天气预报网(http://tqybw.net)优化的一些等记,后续优化的问题会更新上来

    1. 索引很重要

  之前列举记录用了下面的语句。state字段为索引。

  SELECT * FROM history WHERE state='ok' AND feed_url<>'' LIMIT N,10

  当记录数量很大时,有几万之后,这句SQL就很慢了。主要是因为feed_url没有建立索引。后来的解决方法是,把feed_url为空的,设为一个ok以外的state值,就行了。

作为条件查询字段,类型最好按需求长度越小越好,整型比字符好!

  2. 索引不是万能的

  为了计算记录总数,下面的语句会很慢。

  mysql> SELECT COUNT(*) FROM feed_urls WHERE state='error';

  +----------+

  | COUNT(*) |

  +----------+

  | 30715 |

  +----------+

  1 row in set (0.14 sec)

  mysql> EXPLAIN SELECT COUNT(*) FROM feed_urls WHERE state='error'\G

  *************************** 1. row ***************************

  id: 1

  select_type: SIMPLE

  table: feed_urls

  type: ref

  possible_keys: state,page_index

  key: page_index

  key_len: 10

  ref: const

  rows: 25936

  Extra: Using where; Using index

  1 row in set (0.00 sec)

 

  state为索引,请求用时140ms。遍历了state='error'索引下的每一条记录。

 

  mysql> SELECT state,COUNT(*) FROM feed_urls GROUP BY state;

  +----------+----------+

  | state | COUNT(*) |

  +----------+----------+

  | error | 30717 |

  | fetching | 8 |

  | nofeed | 76461 |

  | ok | 74703 |

  | queued | 249681 |

  +----------+----------+

  5 rows in set (0.55 sec)

  mysql> EXPLAIN SELECT state,COUNT(*) FROM feed_urls GROUP BY state\G

  *************************** 1. row ***************************

  id: 1

  select_type: SIMPLE

  table: feed_urls

  type: index

  possible_keys: NULL

  key: state

  key_len: 10

  ref: NULL

  rows: 431618

  Extra: Using index

  1 row in set (0.00 sec)

 

  请求用时550ms。遍历了每个state下的每一条记录。

  改进方法:

  独立一个表用来计数,使用MySQL的Trigger同步计数:

 

  CREATE TRIGGER my_trigger AFTER UPDATE ON feed_urls

  FOR EACH ROW BEGIN

  IF OLD.state <> NEW.state THEN

  IF NEW.state='ok' THEN

  UPDATE feed_stat SET count_feed = count_feed + 1;

  END IF;

  IF NEW.state IN ('ok', 'error', 'nofeed') THEN

  UPDATE feed_stat SET count_access = count_access + 1;

  END IF;

  END IF;

  END

 

  3. 当分页很大时

 

  mysql> SELECT * FROM feed_urls LIMIT 230000, 1\G

  *************************** 1. row ***************************

  id: 736841f82abb0bc87ccfec7c0fdbd09c30b5a24d

  link: http://tqybw.net

  title: Tim Peterson

  feed_url: NULL

  update_time: 2012-05-12 11:01:56

  state: queued

  http_server: NULL

  abstract: NULL

  previous_id: ceea30e0ba609b69198c53ce71c44070d69038c5

  ref_count: 1

  error: NULL

  aid: 230001

  1 row in set (0.50 sec)

  mysql> EXPLAIN SELECT * FROM feed_urls LIMIT 230000, 1\G

  *************************** 1. row ***************************

  id: 1

  select_type: SIMPLE

  table: feed_urls

  type: ALL

  possible_keys: NULL

  key: NULL

  key_len: NULL

  ref: NULL

  rows: 431751

  Extra:

  1 row in set (0.00 sec)

 

  读取一条记录,耗时500ms,因为表记录是变长的,所以MySQL不能算出目标位置,只能每一条记录的数过去。

  改进方法:

  通过索引定位,数索引比数记录要快,因为索引占用的空间比整条记录小很多。

 

  mysql> SELECT * FROM (SELECT aid FROM feed_urls ORDER BY aid LIMIT 215000, 1) d JOIN feed_urls u ON d.aid=u.aid\G

  *************************** 1. row ***************************

  aid: 215001

  id: 2e4b1a385c8aae40b3ec2af9153805ca446f2029

  link: http://tqybw.net

  title: NCSE

  feed_url: NULL

  update_time: 2012-05-12 10:47:15

  state: queued

  http_server: NULL

  abstract: NULL

  previous_id: 819a6e3c5edc1624a9b8f171d8d3ae269843785f

  ref_count: 3

  error: NULL

  aid: 215001

  1 row in set (0.06 sec)

  mysql> EXPLAIN SELECT * FROM (SELECT aid FROM feed_urls ORDER BY aid LIMIT 215000, 1) d JOIN feed_urls u ON d.aid=u.aid\G

  *************************** 1. row ***************************

  id: 1

  select_type: PRIMARY

  table:

  type: system

  possible_keys: NULL

  key: NULL

  key_len: NULL

  ref: NULL

  rows: 1

  Extra:

  *************************** 2. row ***************************

  id: 1

  select_type: PRIMARY

  table: u

  type: const

  possible_keys: aid

  key: aid

  key_len: 4

  ref: const

  rows: 1

  Extra:

  *************************** 3. row ***************************

  id: 2

  select_type: DERIVED

  table: feed_urls

  type: index

  possible_keys: NULL

  key: aid

  key_len: 4

  ref: NULL

  rows: 211001

  Extra: Using index

  3 rows in set (0.15 sec)

 

  耗时60ms,比之前的方法快了将近10倍。如果LIMIT语句里还有WHERE a=1,应该建立一个(a,aid)的索引。

  话说,MySQL好像还是不能直接算出第21500条索引的位置呀,这种方法还是数了索引了,能算出来就直接0ms了。不过这样的效率,对于百万级的,还能应付吧。如果是千万级的或者像我之前在KS创建的一张上亿条记录的表(120G),这种方法就肯定不行了。

  经过上述优化,打开最后一页的速度已经很快了(之前需要800ms,现在则为300ms左右)。

 

  膜拜下这Burst.NET最低档次的VPS (30RMB/month)。

  root@xiaoxia-pc:~/# ping feed.readself.com -n

  PING app.readself.com (184.82.185.32) 56(84) bytes of data.

  64 bytes from 184.82.185.32: icmp_req=1 ttl=45 time=161 ms

  64 bytes from 184.82.185.32: icmp_req=2 ttl=45 time=161 ms

  64 bytes from 184.82.185.32: icmp_req=3 ttl=45 time=161 ms

  用同样的方法,优化了搜索引擎的排名算法。即排名过程中选取尽量少的值出来排序,排序后再JOIN一次获取结果的信息。

  排序过程如下:

 

  SELECT u.*, count_level(u.id) lv

  FROM(

  SELECT f.id, f.ref_count, MATCH(i.link,i.title) AGAINST (keywords) score

  FROM feed_index i

  JOIN feed_urls f ON f.id=i.id

  WHERE MATCH(i.link,i.title) AGAINST (keywords)

  ORDER BY score*0.5 + score*0.5*(ref_count/max_ref_count_in_result) DESC

  LIMIT offset,10

  ) d JOIN feed_urls u ON u.id = d.id

 

  目前处理10万记录的全文索引数据,MySQL还是可以满足的,就是不知道上百万之后,还能不能撑下去。撑不下去就依赖第三方的工具了,例如Sphinx

或者采用其它方法,如ID值起始法!

 

平时项目中还有很多有关mysql的优化方法!用到时有时间再贴出来!

分享到:
评论

相关推荐

    MySQL数据库性能优化之表结构优化

    这里我整理了一些比较常见的数据库表结构设计方面的优化技巧,希望对大家有用。  这是 MySQL数据库性能优化专题 系列的第二篇文章:MySQL 数据库性能优化之表结构优化  系列的第一篇文章:MySQL 数据库性能优化...

    MySQL 数据库面试题

    这是一个汇总了十道常见 MySQL 面试题以及详细答案的资源。涵盖了数据库事务、索引、关系型数据库...因此,建议在学习和使用 MySQL 时,继续深入研究和探索更多的主题和技术,以便更全面地掌握数据库管理和优化的技巧。

    2017最新老男孩MySQL高级专业DBA实战课程全套【清晰不加密】,看完教程月入40万没毛病

    第十五部 MySQL数据库优化思想与优化实战(9节) 1-网站打开慢mysql问题多解决方案企业案例.avi 2-MySQL索引优化要点精讲01 3-MySQL索引优化生产案例讲解02 4-linux运维人员必须掌握的核心经验案例.avi MySQL数据库...

    MYSQL优化详情大全

    以下是一些常见的MySQL优化方法和技巧的描述: 优化数据库结构:设计良好的数据库结构可以提高查询效率。包括正确选择数据类型、合理设置索引、避免冗余字段等。 优化查询语句:编写高效的查询语句可以减少数据库...

    mysql面试题以及相关技巧经验总结(常见错误、常用命令速查手册、开发优化与管理维护、常见面试题、面试技巧、职业规划).zip

    mysql面试题以及相关技巧经验总结(MySQL常见错误及解决方案、MySQL常用命令速查手册、深入浅出MySQL数据库开发、优化与管理维护、常见面试题、面试技巧、职业规划、经验及技巧大汇总)

    数据库索引设计与优化.pdf

    豆瓣8.4分,数据库索引设计必读的好书。 高清扫描版,带完整章节书签(不是网上常见的页码书签的版本!!!!)

    数据库原理(第5版)

    当然,我们还更新了本书所有其他产品的信息,尤其是本版使用Windows 7操作系统来演示本书中的应用程序,MySQL工作台现在是MySQL数据库开发的GUI。 我们继续保持并改进了本书前几版引入的几个特性: ● 在每章中使用...

    整理网上常见的SQL优化技巧

    整理网上常见的SQL优化技巧

    mysql进阶知识以及面试常考知识

    通过深入讲解,用户能够更好地掌握MySQL的高级特性和优化技巧。 面试准备:该资源重点关注面试中常考的MySQL知识点,提供面试题目和答案解析,帮助用户熟悉常见的面试问题和回答技巧。用户可以通过学习这些面试常考...

    MYSQL

    10.6 选择一种表类型 10.6.1 静态(定长)表的特点 10.6.2 动态表的特点 10.6.3 压缩表的特点 10.6.4 内存(In-memory table)表的特点 10.7 其他优化技巧 10.8 使用你自己的基准测试 ...

    MySQL中文参考手册.chm

    10.6 选择一种表类型 10.6.1 静态(定长)表的特点 10.6.2 动态表的特点 10.6.3 压缩表的特点 10.6.4 内存(In-memory table)表的特点 10.7 其他优化技巧 10.8 使用你自己的基准测试...

    MySQL中文参考手册

    + 7.1.5 数据库,表,索引,列和别名的命名 # 7.1.5.1 名字的大小写敏感性 o 7.2 用户变量 o 7.3 列类型 + 7.3.1 列类型的存储要求 + 7.3.5 数字类型 + 7.3.6 日期和时间类型 # 7.3.6.1 问题和日期类型 # ...

    MySQL面试全面解析手册

    该手册详细介绍了MySQL数据库的基本概念、SQL语法、常见查询优化技巧以及高级主题如索引优化、事务处理和复制等。通过系统化的知识点总结、实用的示例和深入的解读,该手册帮助读者深入理解MySQL的工作原理和最佳...

    MySQL 5.1中文手冊

    7.2.19. 其它优化技巧 7.3. 锁定事宜 7.3.1. 锁定方法 7.3.2. 表锁定事宜 7.4. 优化数据库结构 7.4.1. 设计选择 7.4.2. 使你的数据尽可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6. MyISAM...

    PHP数据库编程之MySQL优化策略概述

    但在一些数据库类扩展像memcache、mongodb、redis这样的数据存储服务器的帮助下,PHP也能达到更快的存取速度,所以了解学习这些扩展也是非常必要,这一篇先说一下MySQL常见的优化策略。 几条MySQL小技巧 1、SQL语句...

    MySQL 5.1官方简体中文参考手册

    7.2.19. 其它优化技巧 7.3. 锁定事宜 7.3.1. 锁定方法 7.3.2. 表锁定事宜 7.4. 优化数据库结构 7.4.1. 设计选择 7.4.2. 使你的数据尽可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 ...

    MySQL 5.1参考手册

    7.2.19. 其它优化技巧 7.3. 锁定事宜 7.3.1. 锁定方法 7.3.2. 表锁定事宜 7.4. 优化数据库结构 7.4.1. 设计选择 7.4.2. 使你的数据尽可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6. MyISAM...

    MySQL 5.1参考手册 (中文版)

    7.2.19. 其它优化技巧 7.3. 锁定事宜 7.3.1. 锁定方法 7.3.2. 表锁定事宜 7.4. 优化数据库结构 7.4.1. 设计选择 7.4.2. 使你的数据尽可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6. MyISAM...

    MySQL 5.1参考手册中文版

    7.2.19. 其它优化技巧 7.3. 锁定事宜 7.3.1. 锁定方法 7.3.2. 表锁定事宜 7.4. 优化数据库结构 7.4.1. 设计选择 7.4.2. 使你的数据尽可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6....

Global site tag (gtag.js) - Google Analytics