`
lenxen
  • 浏览: 31261 次
  • 性别: 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数据库的开发过程、性能优化技巧以及日常管理维护方法,从而更好地利用MySQL数据库为业务提供支持。

    千金良方:MySQL性能优化金字塔法则.docx

    MySQL性能优化金字塔法则 ...通过阅读本书,大家将深入了解MySQL性能优化的各个方面,掌握实用的优化技巧,提高应用程序的性能和可靠性。本书适合开发人员、数据库管理员以及对MySQL性能优化感兴趣的读者阅读。

    MySQL数据库考试练习题 mysql试题集 共28页.pdf

    根据提供的文件信息,我们可以推断出这份文档主要包含MySQL数据库相关的考试练习题目。MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS),因其性能稳定、易于使用和成本低廉等特点,在互联网应用开发中非常...

    MySQL数据库巡检手册

    5. **查询优化**:探讨SQL查询性能优化技巧,包括索引策略、JOIN操作、子查询优化、避免全表扫描等。 6. **存储引擎**:深入分析InnoDB和MyISAM等常见存储引擎的工作原理、优缺点及适用场景,以及如何选择合适的...

    mysql数据库DBA宝典手册

    通过《mysql_database_DBA宝典手册》的学习,读者可以系统地掌握MySQL数据库的管理技巧,从而在实际工作中游刃有余地应对各种挑战,确保数据库系统的高效、稳定运行。配合`mysql_study.pdf`这份文档,读者可以...

    MySQL数据库应用教程

    MySQL数据库应用教程是一份全面而实用的学习资源,旨在帮助初学者和有一定经验的用户深入了解和掌握MySQL数据库系统。这份教程涵盖了MySQL的安装过程、基本概念、语法结构以及实际操作技巧,使得学习者能够快速上手...

    MySQL索引优化课件

    本课件主要聚焦于MySQL数据库的索引原理、优化策略以及相关存储过程和触发器的应用。 首先,我们要理解什么是索引。索引就像书的目录,它为数据库中的数据提供快速访问的途径。在MySQL中,常见的索引类型有B-Tree...

    如何导入超大MySQL数据库备份文件

    常见的MySQL数据库管理工具如phpMyAdmin因其直观的操作界面和丰富的功能被广泛使用。然而,当面对超大数据库备份文件时,phpMyAdmin等通用工具往往力不从心,尤其是在网络条件不佳的情况下,可能导致恢复过程失败或...

    mysql 数据库开发技术手册

    MySQL数据库开发技术手册是一本深度探讨MySQL数据库设计与开发的宝贵资源,对于任何希望深入了解或提升MySQL技能的开发者来说,都是不可或缺的工具。MySQL是一种广泛使用的开源关系型数据库管理系统,以其高效、稳定...

    MySQL数据库性能监控与诊断

    总之,MySQL数据库性能监控与诊断是一个复杂但至关重要的领域,它不仅要求DBA掌握相关的技术工具,还需要具备深厚的数据分析能力和问题解决技巧。通过构建和优化监控系统,可以有效提升数据库的性能,保障业务的顺利...

    mysql数据库编程规范

    - **优化技巧**:合理使用索引和条件过滤以优化连接查询的性能。 ##### 5.7 分页查询规范 - **分页参数**:通过`LIMIT`和`OFFSET`实现分页查询,注意合理设置分页大小以平衡性能和实用性。 #### 6. 脚本规范 - **...

    MYSQL数据库显示工具

    以下是一些关于MySQL数据库显示工具及其相关组件的知识点: 1. MySQL数据库:MySQL是一种流行的开源关系型数据库管理系统(RDBMS),由Oracle公司维护。它以高效、稳定和易用著称,广泛应用于Web应用、数据分析和...

    MySQL数据库优化

    ### MySQL数据库优化知识点详解 #### 一、优化概述与MySQL设计局限性 **优化概述** - **重要性**: 数据库优化对于提升系统性能至关重要。它不仅涉及到技术层面的改进,还包括对业务流程的理解和调整。 - **常见...

    Mysql数据库备份

    ### MySQL数据库备份方法详解 #### 一、引言 ...以上就是关于MySQL数据库备份的一些基础知识和实用技巧,希望能对大家有所帮助。在日常工作中,请务必重视数据备份的重要性,为企业的数据安全保驾护航。

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

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

    MySql数据库课件

    MySQL数据库是世界上最受欢迎的开源关系型数据库管理系统之一,它以其高效、可靠和易于管理的特点深受开发者喜爱。本课件将全面覆盖MySQL的多个关键知识点,帮助你深入理解并掌握其核心功能。 首先,我们从安装...

    精确分析MySQL数据库中优化WHERE子句

    精确分析MySQL数据库中优化WHERE子句 在 MySQL 数据库中,WHERE 子句的优化是非常重要的,因为它可以极大地提高查询的效率。本文将详细分析 MySQL 数据库中优化 WHERE 子句的方法和技巧。 删除不必要的括号 在 ...

Global site tag (gtag.js) - Google Analytics