符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
如何提高MySQL Limit查询的性能?\x0d\x0a在MySQL数据库操作中,我们在做一些查询的时候总希望能避免数据库引擎做全表扫描,因为全表扫描时间长,而且其中大部分扫描对客户端而言是没有意义的。其实我们可以使用Limit关键字来避免全表扫描的情况,从而提高效率。\x0d\x0a有个几千万条记录的表 on MySQL 5.0.x,现在要读出其中几十万万条左右的记录。常用方法,依次循环: \x0d\x0aselect * from mytable where index_col = xxx limit offset, limit; \x0d\x0a\x0d\x0a经验:如果没有blob/text字段,单行记录比较小,可以把 limit 设大点,会加快速度。\x0d\x0a问题:头几万条读取很快,但是速度呈线性下降,同时 mysql server cpu 99% ,速度不可接受。 \x0d\x0a调用 explain select * from mytable where index_col = xxx limit offset, limit; \x0d\x0a显示 type = ALL \x0d\x0a在 MySQL optimization 的文档写到"All"的解释 \x0d\x0aA full table scan is done for each combination of rows from the previous tables. This is normally not good if the table is the first table not marked const, and usually very bad in all other cases. Normally, you can avoid ALL by adding indexes that allow row retrieval from the table based on constant values or column values from earlier tables. \x0d\x0a看样子对于 all, mysql 就使用比较笨的方法,那就改用 range 方式? 因为 id 是递增的,也很好修改 sql 。\x0d\x0aselect * from mytable where id offset and id SELECT * FROM table LIMIT 5,10; //检索记录行6-15\x0d\x0a\x0d\x0a//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为-1\x0d\x0amysql SELECT * FROM table LIMIT 95,-1; //检索记录行96-last\x0d\x0a\x0d\x0a//如果只给定一个参数,它表示返回最大的记录行数目,换句话说,LIMIT n 等价于 LIMIT 0,n\x0d\x0amysql SELECT * FROM table LIMIT 5; //检索前5个记录行\x0d\x0a\x0d\x0aMySQL的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。同样是取10条数据,下面两句就不是一个数量级别的。\x0d\x0aselect * from table limit 10000,10\x0d\x0aselect * from table limit 0,10\x0d\x0a\x0d\x0a文中不是直接使用limit,而是首先获取到offset的id然后直接使用limit size来获取数据。根据他的数据,明显要好于直接使用limit。\x0d\x0a这里我具体使用数据分两种情况进行测试。\x0d\x0a1、offset比较小的时候:\x0d\x0aselect * from table limit 10,10 \x0d\x0a//多次运行,时间保持在0.0004-0.0005之间\x0d\x0aSelect * From table Where vid >=(Select vid From table Order By vid limit 10,1) limit 10 \x0d\x0a//多次运行,时间保持在0.0005-0.0006之间,主要是0.0006\x0d\x0a\x0d\x0a结论:偏移offset较小的时候,直接使用limit较优。这个显然是子查询的原因。\x0d\x0a2、offset大的时候:\x0d\x0aselect * from table limit 10000,10 \x0d\x0a//多次运行,时间保持在0.0187左右\x0d\x0a\x0d\x0aSelect * From table Where vid >=(Select vid From table Order By vid limit 10000,1) limit 10\x0d\x0a//多次运行,时间保持在0.0061左右,只有前者的1/3。可以预计offset越大,后者越优。
发展壮大离不开广大客户长期以来的信赖与支持,我们将始终秉承“诚信为本、服务至上”的服务理念,坚持“二合一”的优良服务模式,真诚服务每家企业,认真做好每个细节,不断完善自我,成就企业,实现共赢。行业涉及成都效果图设计等,在重庆网站建设、全网整合营销推广、WAP手机网站、VI设计、软件开发等项目上具有丰富的设计经验。
数据库优化一方面是找出系统的瓶颈,提高MySQL数据库的整体性能,而另一方面需要合理的结构设计和参数调整,以提高用户的相应速度,同时还要尽可能的节约系统资源,以便让系统提供更大的负荷.
1. 优化一览图
2. 优化
笔者将优化分为了两大类,软优化和硬优化,软优化一般是操作数据库即可,而硬优化则是操作服务器硬件及参数设置.
2.1 软优化
2.1.1 查询语句优化
1.首先我们可以用EXPLAIN或DESCRIBE(简写:DESC)命令分析一条查询语句的执行信息.
2.例:
显示:
其中会显示索引和查询数据读取数据条数等信息.
2.1.2 优化子查询
在MySQL中,尽量使用JOIN来代替子查询.因为子查询需要嵌套查询,嵌套查询时会建立一张临时表,临时表的建立和删除都会有较大的系统开销,而连接查询不会创建临时表,因此效率比嵌套子查询高.
2.1.3 使用索引
索引是提高数据库查询速度最重要的方法之一,关于索引可以参高笔者MySQL数据库索引一文,介绍比较详细,此处记录使用索引的三大注意事项:
2.1.4 分解表
对于字段较多的表,如果某些字段使用频率较低,此时应当,将其分离出来从而形成新的表,
2.1.5 中间表
对于将大量连接查询的表可以创建中间表,从而减少在查询时造成的连接耗时.
2.1.6 增加冗余字段
类似于创建中间表,增加冗余也是为了减少连接查询.
2.1.7 分析表,,检查表,优化表
分析表主要是分析表中关键字的分布,检查表主要是检查表中是否存在错误,优化表主要是消除删除或更新造成的表空间浪费.
1. 分析表: 使用 ANALYZE 关键字,如ANALYZE TABLE user;
2. 检查表: 使用 CHECK关键字,如CHECK TABLE user [option]
option 只对MyISAM有效,共五个参数值:
3. 优化表:使用OPTIMIZE关键字,如OPTIMIZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE user;
LOCAL|NO_WRITE_TO_BINLOG都是表示不写入日志.,优化表只对VARCHAR,BLOB和TEXT有效,通过OPTIMIZE TABLE语句可以消除文件碎片,在执行过程中会加上只读锁.
2.2 硬优化
2.2.1 硬件三件套
1.配置多核心和频率高的cpu,多核心可以执行多个线程.
2.配置大内存,提高内存,即可提高缓存区容量,因此能减少磁盘I/O时间,从而提高响应速度.
3.配置高速磁盘或合理分布磁盘:高速磁盘提高I/O,分布磁盘能提高并行操作的能力.
2.2.2 优化数据库参数
优化数据库参数可以提高资源利用率,从而提高MySQL服务器性能.MySQL服务的配置参数都在my.cnf或my.ini,下面列出性能影响较大的几个参数.
2.2.3 分库分表
因为数据库压力过大,首先一个问题就是高峰期系统性能可能会降低,因为数据库负载过高对性能会有影响。另外一个,压力过大把你的数据库给搞挂了怎么办?所以此时你必须得对系统做分库分表 + 读写分离,也就是把一个库拆分为多个库,部署在多个数据库服务上,这时作为主库承载写入请求。然后每个主库都挂载至少一个从库,由从库来承载读请求。
2.2.4 缓存集群
如果用户量越来越大,此时你可以不停的加机器,比如说系统层面不停加机器,就可以承载更高的并发请求。然后数据库层面如果写入并发越来越高,就扩容加数据库服务器,通过分库分表是可以支持扩容机器的,如果数据库层面的读并发越来越高,就扩容加更多的从库。但是这里有一个很大的问题:数据库其实本身不是用来承载高并发请求的,所以通常来说,数据库单机每秒承载的并发就在几千的数量级,而且数据库使用的机器都是比较高配置,比较昂贵的机器,成本很高。如果你就是简单的不停的加机器,其实是不对的。所以在高并发架构里通常都有缓存这个环节,缓存系统的设计就是为了承载高并发而生。所以单机承载的并发量都在每秒几万,甚至每秒数十万,对高并发的承载能力比数据库系统要高出一到两个数量级。所以你完全可以根据系统的业务特性,对那种写少读多的请求,引入缓存集群。具体来说,就是在写数据库的时候同时写一份数据到缓存集群里,然后用缓存集群来承载大部分的读请求。这样的话,通过缓存集群,就可以用更少的机器资源承载更高的并发。
一个完整而复杂的高并发系统架构中,一定会包含:各种复杂的自研基础架构系统。各种精妙的架构设计.因此一篇小文顶多具有抛砖引玉的效果,但是数据库优化的思想差不多就这些了.
我们都知道,服务器数据库的开发一般都是通过java或者是PHP语言来编程实现的,而为了提高我们数据库的运行速度和效率,数据库优化也成为了我们每日的工作重点,今天,昌平IT培训就一起来了解一下mysql服务器数据库的优化方法。
为什么要了解索引真实案例案例一:大学有段时间学习爬虫,爬取了知乎300w用户答题数据,存储到mysql数据中。
那时不了解索引,一条简单的“根据用户名搜索全部回答的sql“需要执行半分钟左右,完全满足不了正常的使用。
案例二:近线上应用的数据库频频出现多条慢sql风险提示,而工作以来,对数据库优化方面所知甚少。
例如一个用户数据页面需要执行很多次数据库查询,性能很慢,通过增加超时时间勉强可以访问,但是性能上需要优化。
索引的优点合适的索引,可以大大减小mysql服务器扫描的数据量,避免内存排序和临时表,提高应用程序的查询性能。
索引的类型mysql数据中有多种索引类型,primarykey,unique,normal,但底层存储的数据结构都是BTREE;有些存储引擎还提供hash索引,全文索引。
BTREE是常见的优化要面对的索引结构,都是基于BTREE的讨论。
B-TREE查询数据简单暴力的方式是遍历所有记录;如果数据不重复,就可以通过组织成一颗排序二叉树,通过二分查找算法来查询,大大提高查询性能。
而BTREE是一种更强大的排序树,支持多个分支,高度更低,数据的插入、删除、更新更快。
现代数据库的索引文件和文件系统的文件块都被组织成BTREE。
btree的每个节点都包含有key,data和只想子节点指针。
btree有度的概念d=1。
假设btree的度为d,则每个内部节点可以有n=[d+1,2d+1)个key,n+1个子节点指针。
树的大高度为h=Logb[(N+1)/2]。
索引和文件系统中,B-TREE的节点常设计成接近一个内存页大小(也是磁盘扇区大小),且树的度非常大。
这样磁盘I/O的次数,就等于树的高度h。
假设b=100,一百万个节点的树,h将只有3层。
即,只有3次磁盘I/O就可以查找完毕,性能非常高。
索引查询建立索引后,合适的查询语句才能大发挥索引的优势。
另外,由于查询优化器可以解析客户端的sql语句,会调整sql的查询语句的条件顺序去匹配合适的索引。
优化“mysql数据库”来提高“mysql性能”的方法有:
1、选取最适用的字段属性。
MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。
2、使用连接(JOIN)来代替子查询(Sub-Queries)。
MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。
3、使用联合(UNION)来代替手动创建的临时表。
MySQL 从4.0的版本开始支持UNION查询,它可以把需要使用临时表的两条或更多的SELECT查询合并的一个查询中。在客户端的查询会话结束的时候,临时表会被自动删除,从而保证数据库整齐、高效。
4、事务。
要把某个数据同时插入两个相关联的表中,可能会出现这样的情况:第一个表中成功更新后,数据库突然出现意外状况,造成第二个表中的操作没有完成,这样,就会造成数据的不完整,甚至会破坏数据库中的数据。要避免这种情况,就应该使用事务,它的作用是:要么语句块中每条语句都操作成功,要么都失败。
5、锁定表。
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。
6、使用外键。
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。
7、使用索引
索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(), MIN()和ORDERBY这些命令的时候,性能提高更为明显。
8、优化的查询语句
绝大多数情况下,使用索引可以提高查询的速度,但如果SQL语句使用不恰当的话,索引将无法发挥它应有的作用。