MySQL优化宝典

MySQL优化宝典
MySQL优化宝典

Optimize

优化概述

最常见的系统瓶颈是:

●磁盘搜索。优化它的方法是将数据分布在多个磁盘上。

●磁盘读/写。这比搜索要容易优化,因为你能从多个磁盘并行地读。

●CPU周期。我们将数据读入内存后,需要对它进行处理以获得我们需要的结果。表

相对于内存较小是最常见的限制因素。但是对于小表,速度通常不成问题。

●内存带宽。当CPU需要的数据超出CPU缓存时,主缓存带宽就成为内存的一个瓶

颈。这在大多数系统正是一个不常见的瓶颈但是你应该知道它。

优化SELECT语句和其它查询

首先,影响所有语句的一个因素是:你的许可设置得越复杂,所需要的开销越多。

执行GRANT语句时使用简单的许可,当客户执行语句时,可以使MySQL降低许可检查开销。

如果你的问题是与具体MySQL表达式或函数有关,可以使用mysql客户程序所带的BENCHMARK()函数执行定时测试。其语法为BENCHMARK(loop_count,expression)。

EXPLAIN语法(获取SELECT相关信息)

EXPLAIN tbl_name

或:

EXPLAIN [EXTENDED] SELECT select_options

EXPLAIN语句可以用作DESCRIBE的一个同义词,或获得关于MySQL如何执行SELECT语句的信息:

●EXPLAIN tbl_name是DESCRIBE tbl_name或SHOW COLUMNS FROM

tbl_name的一个同义词。

●如果在SELECT语句前放上关键词EXPLAIN,MySQL将解释它如何处理SELECT,

提供有关表如何联接和联接的次序。

借助于EXPLAIN,可以知道什么时候必须为表加入索引以得到一个使用索引来寻找记录的更快的SELECT。

如果由于使用不正确的索引出现了问题,应运行ANALYZE TABLE更新表的统计(例如关键字集的势),这样会影响优化器进行的选择。

还可以知道优化器是否以一个最佳次序联接表。为了强制优化器让一个SELECT语句按照表命名顺序的联接次序,语句应以STRAIGHT_JOIN而不只是SELECT开头。

EXPLAIN为用于SELECT语句中的每个表返回一行信息。表以它们在处理查询过程中将被MySQL读入的顺序被列出。MySQL用一遍扫描多次联接(single-sweep

multi-join)的方式解决所有联接。这意味着MySQL从第一个表中读一行,然后找到在第二个表中的一个匹配行,然后在第3个表中等等。当所有的表处理完后,它输出选中的列并且返回表清单直到找到一个有更多的匹配行的表。从该表读入下一行并继续处理下一个表。

当使用EXTENDED关键字时,EXPLAIN产生附加信息,可以用SHOW WARNINGS浏览。该信息显示优化器限定SELECT语句中的表和列名,重写并且执行优化规则后SELECT 语句是什么样子,并且还可能包括优化过程的其它注解。

当使用EXTENDED关键字时,EXPLAIN产生附加信息,可以用SHOW WARNINGS浏览。该信息显示优化器限定SELECT语句中的表和列名,重写并且执行优化规则后SELECT 语句是什么样子,并且还可能包括优化过程的其它注解。

EXPLAIN的每个输出行提供一个表的相关信息,并且每个行包括下面的列:

估计查询性能

在大多数情况下,可以通过计算磁盘搜索来估计性能。对小的表,通常能在1次磁盘搜索中找到行(因为索引可能被缓存)。对更大的表,可以使用B-树索引进行估计,将需要log(row_count)/log(index_block_length/3 * 2/(index_length+ data_pointer_length))+1次搜索才能找到行。

可以将大部分索引保存在内存中,仅需要1-2调用从OS读数据来找出行。

然而对于写,将需要4次搜索请求(如上)来找到在哪儿存放新索引,并且通常需要2次搜索来更新这个索引并且写入行。

注意:上述讨论并不意味着应用程序的性能将缓慢地以logN 退化!当表格变得更大时,所有内容缓存到OS或SQL服务器后,将仅仅或多或少地更慢。在数据变得太大不能缓存后,将逐渐变得更慢,直到应用程序只能进行磁盘搜索(以logN增加)。为了避免这个问题,随数据增加而增加键高速缓冲区大小。对于MyISAM表, 由key_buffer_size 系统变量控制键高速缓冲区大小。

SELECT查询的速度

总的来说,要想使一个较慢速SELECT ... WHERE更快,应首先检查是否能增加一个索引。不同表之间的引用通常通过索引来完成。你可以使用EXPLAIN语句来确定SELECT 语句使用哪些索引。

加速对MyISAM表的查询的一般建议:

为了帮助MySQL更好地优化查询,在一个装载数据后的表上运行ANALYZE TABLE 或myisamchk --analyze。这样为每一个索引更新指出有相同值的行的平均行数的值(当然,如果只有一个索引,这总是1。)MySQL使用该方法来决定当你联接两个基于非常量表达式的表时选择哪个索引。你可以使用SHOW INDEX FROM tbl_name并检查Cardinality值来检查表分析结果。myisamchk --description --verbose

可以显示索引分布信息。

●要想根据一个索引排序一个索引和数据,使用myisamchk --sort-index

--sort-records=1(如果你想要在索引1上排序)。如果只有一个索引,想要根据该索引的次序读取所有的记录,这是使查询更快的一个好方法。但是请注意,第一次对一个大表按照这种方法排序时将花很长时间!

MySQL怎样优化WHERE子句

●去除不必要的括号:

●常量重叠:

●去除常量条件(由于常量重叠需要):

●索引使用的常数表达式仅计算一次。

范围优化

单元素索引的范围访问方法

对于单元素索引,可以用WHERE子句中的相应条件很方便地表示索引值区间,因此我们称为范围条件而不是“区间”。

单元素索引范围条件的定义如下:

●对于BTREE和HASH索引,当使用=、<=>、IN、IS NULL或者IS NOT NULL

操作符时,关键元素与常量值的比较关系对应一个范围条件。

●对于BTREE索引,当使用>、<、>=、<=、BETWEEN、!=或者<>,或者LIKE

'pattern'(其中 'pattern'不以通配符开始)操作符时,关键元素与常量值的比较关系对应一个范围条件。

●对于所有类型的索引,多个范围条件结合OR或AND则产生一个范围条件。

前面描述的“常量值”系指:

●查询字符串中的常量

●同一联接中的const或system表中的列

●无关联子查询的结果

●完全从前面类型的子表达式组成的表达式

MySQL尝试为每个可能的索引从WHERE子句提取范围条件。在提取过程中,不能用于构成范围条件的条件被放弃,产生重叠范围的条件组合到一起,并且产生空范围的条件被删除。

范围条件提取算法可以处理嵌套的任意深度的AND/OR结构,并且其输出不依赖条件在WHERE子句中出现的顺序。

多元素索引的范围访问方法

多元素索引的范围条件是单元素索引的范围条件的扩展。多元素索引的范围条件将索引

记录限制到一个或几个关键元组内。使用索引的顺序,通过一系列关键元组来定义关键元组区间。

下面更加详细地描述了范围条件如何用于多元素索引中。

●对于HASH索引,可以使用包含相同值的每个区间。这说明区间只能由下面形式的

条件产生;

●对于BTREE索引,区间可以对结合AND的条件有用,其中每个条件用一个常量值

通过=、<=>、IS NULL、>、<、>=、<=、!=、<>、BETWEEN或者LIKE 'pattern' (其中'pattern'不以通配符开头)比较一个关键元素。区间可以足够长以确定一个包含所有匹配条件(或如果使用<>或!=,为两个区间)的记录的单一的关键元组。

●如果包含区间内的一系列记录的条件结合使用OR,则形成包括一系列包含在区间

并集的记录的一个条件。如果条件结合使用了AND,则形成包括一系列包含在区间交集内的记录的一个条件。

索引合并优化

索引合并方法用于通过range扫描搜索行并将结果合成一个。合并会产生并集、交集或者正在进行的扫描的交集的并集。

在EXPLAIN输出中,该方法表现为type列内的index_merge。在这种情况下,key 列包含一列使用的索引,key_len包含这些索引的最长的关键元素。

索引合并方法有几种访问算法:

●交集

●联合

●排序并集

索引合并交集访问算法

该访问算法可以用于当WHERE子句结合AND被转换为不同的关键字的几个范围条件,每个条件为下面之一:

●以这种形式,即索引有确切的N部分(即包括了所有索引部分);

●任何InnoDB或BDB表的主键的范围条件。

索引合并交集算法同时对所有使用的索引进行扫描,并产生从合并的索引扫描接收的行序列的交集。

如果使用的索引包括查询中使用的所有列,所有表记录均不搜索,并且在这种情况下EXPLAIN的输出包含Extra字段中的Using index。

如果使用的索引未包括查询中使用的所有列,只有满足所有使用的关键字的范围条件才搜索所有记录。

如果某个合并条件是InnoDB或BDB表的主键的一个条件,不用于记录查询,但用于

过滤使用其它条件搜索的记录。

索引合并并集访问算法

该算法的适用标准类似于索引合并方法交集算法的标准。算法可以用于当WHERE子句结合OR被转换为不同的关键字的几个范围条件的时候,每个条件为下面之一:

●以这种形式,即索引有确切的N部分(即包括了所有索引部分):

key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

●任何InnoDB或BDB表的主键的范围条件。

●索引合并方法交集算法适用的一个条件。

MySQL如何优化IS NULL

MySQL可以对可以结合col_name = constant_value使用的col_name IS NULL 进行相同的优化。

如果WHERE子句包括声明为NOT NULL的列的col_name IS NULL条件,表达式则优化。当列会产生NULL时,不会进行优化。

MySQL也可以优化组合col_name = expr AND col_name IS NULL,这是解决子查询的一种常用形式。当使用优化时EXPLAIN显示ref_or_null。

该优化可以为任何关键元素处理IS NULL。

MySQL如何优化DISTINCT

在许多情况下结合ORDER BY的DISTINCT需要一个临时表。

请注意因为DISTINCT可能使用GROUP BY,必须清楚MySQL如何使用所选定列的一部分的ORDER BY或HAVING子句中的列。

在大多数情况下,DISTINCT子句可以视为GROUP BY的特殊情况。

MySQL如何优化LEFT JOIN和RIGHT JOIN

在MySQL中,A LEFT JOIN B join_condition执行过程如下:

●根据表A和A依赖的所有表设置表B。

●根据LEFT JOIN条件中使用的所有表(除了B)设置表A。

●LEFT JOIN条件用于确定如何从表B搜索行。

●可以对所有标准联接进行优化,只是只有从它所依赖的所有表读取的表例外。如果

出现循环依赖关系,MySQL提示出现一个错误。

●进行所有标准WHERE优化。

●如果A中有一行匹配WHERE子句,但B中没有一行匹配ON条件,则生成另一个

B行,其中所有列设置为NULL。

●如果使用LEFT JOIN找出在某些表中不存在的行,并且进行了下面的测试:WHERE

部分的col_name IS NULL,其中col_name是一个声明为 NOT NULL的列,MySQL 找到匹配LEFT JOIN条件的一个行后停止(为具体的关键字组合)搜索其它行。

MySQL如何优化嵌套Join

●对于只包含内联接(而非外联接)的联接表达式,可以删除括号。你可以移除括号

并从左到右评估(或实际上,你可以按任何顺序评估表)。

●总的来说,对外联接却不是这样。去除括号可能会更改结果。

●总的来说,对外联接和内联接的结合,也不是这样。去除括号可能会更改结果。

MySQL如何简化外部联合

在许多情况下,一个查询的FROM子句的表的表达式可以简化。

MySQL如何优化ORDER BY

在某些情况中,MySQL可以使用一个索引来满足ORDER BY子句,而不需要额外的排序。

即使ORDER BY不确切匹配索引,只要WHERE子句中的所有未使用的索引部分和所有额外的ORDER BY 列为常数,就可以使用索引。

在某些情况下,MySQL不能使用索引来解决ORDER BY,尽管它仍然使用索引来找到匹配WHERE子句的行。这些情况包括:

●对不同的关键字使用ORDER BY:

●对关键字的非连续元素使用ORDER BY:

●混合ASC和DESC:

●用于查询行的关键字与ORDER BY中所使用的不相同:

●你正联接许多表,并且ORDER BY中的列并不是全部来自第1个用于搜索行的非

常量表。

●有不同的ORDER BY和GROUP BY表达式。

●使用的表索引的类型不能按顺序保存行。

如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。如果不能,可以尝试下面的策略:

●增加sort_buffer_size变量的大小。

●增加read_rnd_buffer_size变量的大小。

●更改tmpdir指向具有大量空闲空间的专用文件系统。该选项接受几个使用

round-robin(循环)模式的路径。在Unix中路径应用冒号(‘:’)区间开,在Windows、NetWare和OS/2中用分号(‘;’)。可以使用该特性将负载均分到几个目录中。注释:路径应为位于不同物理硬盘上的文件系统的目录,而不是同一硬盘的不同的分区。

默认情况下,MySQL排序所有GROUP BY col1,col2,...查询的方法如同在查询中指定ORDER BY col1,col2,...。如果显式包括一个包含相同的列的ORDER BY子句,MySQL可以毫不减速地对它进行优化,尽管仍然进行排序。

MySQL如何优化GROUP BY

满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有)。在某些情况中,MySQL能够做得更好,通过索引访问而不用创建临时表。

为GROUP BY使用索引的最重要的前提条件是所有GROUP BY列引用同一索引的属性,并且索引按顺序保存其关键字。是否用索引访问来代替临时表的使用还取决于在查询中使用了哪部分索引、为该部分指定的条件,以及选择的累积函数。

散索引扫描

使用索引时最有效的途径是直接搜索组域。通过该访问方法,MySQL使用某些关键字排序的索引类型的属性。该属性允许使用索引中的查找组而不需要考虑满足所有WHERE 条件的索引中的所有关键字。既然该访问方法只考虑索引中的关键字的一小部分,它被称为松散索引扫描。如果没有WHERE子句,松散索引扫描读取的关键字数量与组数量一样多,可以比所有关键字数小得多。如果WHERE子句包含范围判断式,松散索引扫描查找满足范围条件的每个组的第1个关键字,并且再次读取尽可能最少数量的关键字。在下面的条件下是可以的:

●查询针对一个单表。

●GROUP BY包括索引的第1个连续部分(如果对于GROUP BY,查询有一个

DISTINCT子句,则所有显式属性指向索引开头)。

●只使用累积函数(如果有)MIN()和MAX(),并且它们均指向相同的列。

●索引的任何其它部分(除了那些来自查询中引用的GROUP BY)必须为常数(也就

是说,必须按常量数量来引用它们),但MIN()或MAX() 函数的参数例外。

紧凑索引扫描

紧凑式索引扫描可以为索引扫描或一个范围索引扫描,取决于查询条件。

如果不满足松散索引扫描条件,GROUP BY查询仍然可以不用创建临时表。如果WHERE 子句中有范围条件,该方法只读取满足这些条件的关键字。否则,进行索引扫描。该方法读取由WHERE子句定义的每个范围的所有关键字,或没有范围条件式扫描整个索引,我们将它定义为紧凑式索引扫描。请注意对于紧凑式索引扫描,只有找到了满足范围条件的所有关键字后才进行组合操作。

要想让该方法工作,对于引用GROUP BY关键字元素的前面、中间关键字元素的查询中的所有列,有一个常量等式条件即足够了。等式条件中的常量填充了搜索关键字中的“差距”,可以形成完整的索引前缀。这些索引前缀可以用于索引查找。如果需要排序GROUP BY 结果,并且能够形成索引前缀的搜索关键字,MySQL还可以避免额外的排序操作,因为使用有顺序的索引的前缀进行搜索已经按顺序检索到了所有关键字。

MySQL如何优化LIMIT

在一些情况中,当你使用LIMIT row_count而不使用HAVING时,MySQL将以不同方式处理查询。

●如果你用LIMIT只选择一些行,当MySQL选择做完整的表扫描时,它将在一些情

况下使用索引。

●如果你使用LIMIT row_count与ORDER BY,MySQL一旦找到了排序结果的第

一个row_count行,将结束排序而不是排序整个表。如果使用索引,将很快。如果必须进行文件排序(filesort),必须选择所有匹配查询没有LIMIT子句的行,并且在确定已经找到第1个row_count行前,必须对它们的大部分进行排序。在任何一种情况下,一旦找到了行,则不需要再排序结果的其它部分,并且MySQL不再进行排序。

●当结合LIMIT row_count和DISTINCT时,MySQL一旦找到row_count个唯

一的行,它将停止。

●在一些情况下,GROUP BY能通过顺序读取键(或在键上做排序)来解决,然后计

算摘要直到关键字的值改变。在这种情况下,LIMIT row_count将不计算任何不必要的GROUP BY值。

●只要MySQL已经发送了需要的行数到客户端,它将放弃查询,除非你正使用

SQL_CALC_FOUND_ROWS。

●LIMIT 0将总是快速返回一个空集合。这对检查查询的有效性是有用的。当使用

MySQL API时,它也可以用来得到结果列的列类型。(该技巧在MySQL Monitor中不工作,只显示Empty set;应使用SHOW COLUMNS或DESCRIBE)。

●当服务器使用临时表来进行查询时,使用LIMIT row_count子句来计算需要多

少空间。

INSERT语句的速度

插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例:

●连接:(3)

●发送查询给服务器:(2)

●分析查询:(2)

●插入记录:(1x记录大小)

●插入索引:(1x索引)

●关闭:(1)

这不考虑打开表的初始开销,每个并发运行的查询打开。

表的大小以logN (B树)的速度减慢索引的插入。

加快插入的一些方法:

●如果同时从同一个客户端插入很多行,使用含多个VALUE的INSERT语句同时插

入几行。这比使用单行INSERT语句快(在某些情况下快几倍)。如果你正向一个非空表添加数据,可以调节bulk_insert_buffer_size变量,使数据插入更快。

●如果你从不同的客户端插入很多行,能通过INSERT DELAYED语句加快速度。

●用MyISAM,如果在表中没有删除的行,能在SELECT语句正在运行的同时插入行。

●当从一个文本文件装载一个表时,使用LOAD DATA INFILE。这通常比使用很多

INSERT语句快20倍。

●锁定表可以加速用多个语句执行的INSERT操作;

对于事务表,应使用BEGIN和COMMIT代替LOCK TABLES来加快插入。

锁定也将降低多连接测试的整体时间,尽管因为它们等候锁定最大等待时间将上升。

●为了对LOAD DATA INFILE和INSERT在MyISAM表得到更快的速度,通过增

加key_buffer_size系统变量来扩大键高速缓冲区。

UPDATE语句的速度

更新查询的优化同SELECT查询一样,需要额外的写开销。写速度依赖于更新的数据大小和更新的索引的数量。没有更改的索引不被更新。

使更改更快的另一个方法是推迟更改然后在一行内进行多次更新。如果锁定表,同时做多个更新比一次做一个快得多。

请注意对使用动态记录格式的MyISAM表,更新一个较长总长的记录可能会切分记录。如果经常这样该,偶尔使用OPTIMIZE TABLE很重要。

DELETE语句的速度

删除一个记录的时间与索引数量确切成正比。为了更快速地删除记录,可以增加键高速缓冲的大小。

如果想要删除一个表的所有行,使用TRUNCATE TABLE tbl_name 而不要用DELETE FROM tbl_name。

其它优化技巧

该节列出了提高查询速度的各种技巧:

●使用持久的连接数据库以避免连接开销。如果不能使用持久的连接并且你正启动许

多新的与数据库的连接,可能要更改thread_cache_size变量的值。

●总是检查所有查询确实使用已经在表中创建了的索引。在MySQL中,可以用

EXPLAIN命令做到。

●尝试避免在频繁更新的表上执行复杂的SELECT查询,以避免与锁定表有关的由

于读、写冲突发生的问题。

●对于没有删除的行的MyISAM表,可以在另一个查询正从表中读取的同时在末尾

插入行。如果这很重要,应考虑按照避免删除行的方式使用表。另一个可能性是在删除大量行后运行OPTIMIZE TABLE。

●要修复任何ARCHIVE表可以发生的压缩问题,可以执行OPTIMIZE TABLE。

●如果你主要按expr1,expr2,...顺序检索行,使用ALTER TABLE ... ORDER BY expr1, expr2, ...。对表大量更改后使用该选项,可以获得更好的性能。

●在一些情况下,使得基于来自其它表的列的信息引入一个“哈希”的列有意义。如果该列较短并且有合理的唯一值,它可以比在许多列上的一个大索引快些。

●对于频繁更改的MyISAM表,应试图避免所有变长列(VARCHAR、BLOB和TEXT)。如果表包括单一的变长列则使用动态记录格式。

●只是因为行太大,将一张表分割为不同的表一般没有什么用处。为了访问行,最大的性能冲击是磁盘搜索以找到行的第一个字节。在找到数据后,大多数新型磁盘对大多数应用程序来说足够快,能读入整个行。确实有必要分割的唯一情形是如果它是使用动态记录格式使之变为固定的记录大小的MyISAM表(见上述),或如果你需要很频繁地扫描表而不需要大多数列。

●如果你需要很经常地计算结果,引入一个新表并实时更新计数器可能更好一些。下面形式的更新会更快一些:

●当你使用象MyISAM那样的只有表级锁定的MySQL存储引擎(多重读/单个写)时,这确实很重要。这也给大多数数据库较好的性能,因为行锁定管理器在这种情况下有较少的事情要做。

●如果你需要从大的记录文件表中收集统计信息,使用总结性的表而不是扫描整个表。维护总结应该比尝试做“实时”统计要快些。当有变化时从日志重新生成新的总结表比改变运行的应用(取决于业务决策)要快得多。

●如果可能,应该将报告分类为“实时”或“统计”,这里统计报告所需的数据仅仅基于从实际数据定期产生的总结表中产生。

●充分利用列有默认值的事实。只有当插入的值不同于默认值时,才明确地插入值。这减少MySQL需要做的语法分析从而提高插入速度。

●在一些情况下,包装并存储数据到一个BLOB列中是很方便的。在这种情况下,必须在你的应用中增加额外的代码来打包/解包信息,但是这种方法可以在某些阶段节省很多访问。当有不符合行和列表结构的数据时,这很实用。

●在一般情况下,应该尝试以非冗余方式(查看数据库理论中的第三正则形式)保存数据,但是为了获得更快的速度,可以复制信息或创建总结表。

●存储过程或UDF(用户定义函数)可能是获得更好性能的一个好方法。

●总是能通过在应用程序中缓存查询/答案并尝试同时执行很多插入/更新来获得一些好处。如果数据库支持锁定表(象MySQL和Oracle),这应该有助于确保索引缓存只在所有更新后刷新一次。还可以利用MySQL的查询缓存来获得类似的结果。

●当不需要知道何时写入数据时,使用INSERT DELAYED。这样可以加快处理,因

为很多记录可以通过一次磁盘写入被写入。

●当你想要让选择显得更重要时,使用INSERT /*! LOW_PRIORITY */。

●使用INSERT LOW_PRIORITY来取得插入队列的检索,也就是即使有另一个客户等待写入也要执行SELECT。

●使用多行INSERT语句通过一个SQL命令来存储很多行(许多SQL服务器支持它,包括MySQL)。

●使用LOAD DATA INFILE装载较大数量的数据。这比使用INSERT要快得多。

●使用AUTO_INCREMENT列构成唯一值。

●当MyISAM使用动态表格式时,偶尔使用OPTIMIZE TABLE可以避免碎片。

●可能时使用MEMORY表以得到更快的速度。

●在Web服务器中,图象和其它二进制资产应该作为文件存储。也就是仅在数据库中存储的本文件的引用而不是文件本身。大多数Web服务器在缓存文件方面比数据库内容要好得多,因此使用文件一般要快得多。

●对经常访问的不重要数据使用内存表。在许多Web应用程序环境中也可以使用用户会话来处理可变状态数据。

●在不同表中具有相同信息的列应该被声明为相同的并有相同的名字。尝试使名字简单化。为了使名字能移植到其它SQL服务器,应该使名字短于18个字符。

●如果确实需要很高的速度,应该研究一下不同SQL服务器支持的数据存储的低层接口!为了能实现,数据必须与应用程序在同一台服务器上,并且通常只应该被一个进程访问(因为外部文件锁定确实很慢)。通过在MySQL服务器中引进低层MyISAM命令能消除以上问题(如果需要,这可能是获得更好性能的一个简单的方法)。通过精心设计数据库接口,应该能相当容易地支持这类优化。

●如果正使用数字数据,在许多情况下,从一个数据库访问信息(使用实时连接)比访问一个文本文件快些。这是因为数据库中的信息比文本文件更紧凑,因此这将涉及更少的磁盘访问。还可以在应用程序中节省代码,因为不须分析文本文件来找出行和列的边界。

●通过复制可以提高某些操作的性能。可以在复制服务器中分布客户的检索以均分负载。为了防止备份时主服务器变慢,可以使用一个从服务器来备份。

●用DELAY_KEY_WRITE=1选项声明MyISAM表可以使索引更新更快,因为在表关闭之前它们不刷新到硬盘上。不利之处是当表打开时如果杀掉服务器,应确保用--myisam-recover选项运行服务器保证没有问题,或者在重启服务器之前运行myisamchk。

大型ORACLE数据库优化设计方案

大型ORACLE数据库优化设计方案 本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案。 对于ORACLE数据库的数据存取,主要有四个不同的调整级别,第一级调整是操作系统级 包括硬件平台,第二级调整是ORACLE RDBMS级的调整,第三级是数据库设计级的调整,最后一个调整级是SQL级。通常依此四级调整级别对数据库进行调整、优化,数据库的整体性能会得到很大的改善。下面从九个不 同方面介绍ORACLE数据库优化设计方案。 一.数据库优化自由结构OFA(Optimal flexible Architecture) 数据库的逻辑配置对数据库性能有很大的影响,为此,ORACLE公司对表空间设计提出了一种优化结构OFA。使用这种结构进行设计会大大简化物理设计中的数据管理。优化自由结构OFA,简单地讲就是在数据库中可以高效自由地分布逻辑数据对象,因此首先要对数据库中的逻辑对象根据他们的使用方式和物理结构对数据库的影响来进行分类,这种分类包括将系统数据和用户数据分开、一般数据和索引数据分开、低活动表和高活动表分开等等。数据库逻辑设计的结果应当符合下面的准则:(1)把以同样方式使用的段类型存储在一起; (2)按照标准使用来设计系统;(3)存在用于例外的分离区域;(4)最小化表空间冲突;(5)将数 据字典分离。 二、充分利用系统全局区域SGA(SYSTEM GLOBAL AREA) SGA是oracle数据库的心脏。用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的。正确的SGA大小对数据库的性能至关重要。SGA 包括以下几个部分: 1、数据块缓冲区(data block buffer cache)是SGA中的一块高速缓存,占整个数据库大小 的1%-2%,用来存储从数据库重读取的数据块(表、索引、簇等),因此采用least recently used (LRU,最近最少使用)的方法进行空间管理。 2、字典缓冲区。该缓冲区内的信息包括用户账号数据、数据文件名、段名、盘区位置、表 说明和权限,它也采用LRU方式管理。 3、重做日志缓冲区。该缓冲区保存为数据库恢复过程中用于前滚操作。 4、SQL共享池。保存执行计划和运行数据库的SQL语句的语法分析树。也采用LRU算法 管理。如果设置过小,语句将被连续不断地再装入到库缓存,影响系统性能。 另外,SGA还包括大池、JAVA池、多缓冲池。但是主要是由上面4种缓冲区构成。对这

mysql优化笔记

◆Mysql数据库的优化技术<大型网站优化技术> 对mysql优化时一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引] c: 分表技术(水平分割、垂直分割) d: 读写[写: update/delete/add]分离 e: 存储过程[模块化编程,可以提高速度] 数据库的三层结构: f: 对mysql配置优化[配置最大并发数my.ini, 调整缓存大小] g: mysql服务器硬件升级 h: 定时的去清除不需要的数据,定时进行碎片整理(MyISAM) CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name (index_col_name,...) ◆什么样的表才是符合3NF (范式) 表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF 1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解, 只有数据库是关系型数据库(mysql/oracle/db2/informix/sysbase/sql server),就自动的满足1NF ?数据库的分类 关系型数据库: mysql/oracle/db2/informix/sysbase/sql server 非关系型数据库: (特点: 面向对象或者集合) NoSql数据库: MongoDB(特点是面向文档) 2NF: 表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现id primary key ; 3NF: 即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放. 比如下面的设计就是不满足3NF:显示推导处理

数据库及SQL代码优化方案

1.1、数据库及SQL代码优化方案 (1)每周检查统计信息是否及时更新。 (2)每周检查各索引是否有效。 (3)每周检查分区是否正确。 (4)每周检查执行计划是否正确。 (5)每天检查RAC和ASM是否正常运行。 (6)每天检查相关日志是否正常备份。 (7)每天检查相关文件系统和表空间的占用率是否在国家税务总局规定的阀值以下。 (8)在每月申报高峰等业务繁忙期采样并找出消耗I/O资源和CPU资源较多的SQL语句。 (9)分析上述SQL语句,与软件服务商充分沟通后,提出优化建议。 (10)在每月申报高峰期每隔15分钟检查一次数据库连接数,发现异常及时处理。 1.1.1、系统数据库索引、表分区和对象优化方案 数据库对象的优化主要包括:表、索引和sequence等对象,通过优化对象参数、调整对象属性(例如分区表、分区索引、反转索引等等)等方法来实现对数据库对象的优化改造。 1.1.1.1表和索引并行参数优化 数据库的表和索引的并行参数值的设置对相关的sql语句的执行计划会造成影响,表和索引的degree值大于1,执行计划就偏向于使用全表和全索引扫描,另外如果并行参数值过大,短时间内也会对主机和数据库的资源造成很大的压力,因此在oltp的数据库下建议将表和索引的degree值设为1。 1.1.1.2热点大表的分区改造 对访问量很大、表的记录数很多、存在热块争用的表,可以考虑对表和索引进行适当的分区改造,分散访问压力,提高数据访问的性能。 对以下表的记录数超过1000万并且记录数持续增长的大表,建议进行分区

改造(地区+时间): 1.1.1.3分区索引的清理 对最近30天数据库分区索引访问情况进行统计,对访问次数为0的分区索引和应用部门进行确认,若确认为多余的索引,建议进行删除清理。 1.1.1.4Sequence序列优化 加大sequence 的 cache,并使用noorder选项。在RAC中经常会遇到SQ 锁等待,这是因为在RAC环境下,sequence也成为全局性的了,不同节点要生成序列号,就会产生对sequence资源的争用。而目前大多数系统中,sequence 大多数被作为主键发生器来使用,使用的频率十分高,在RAC环境中,需要设置较大的 sequence cache,否则会造成较为严重的争用,从而影响业务。 1.1.2、SQL硬解析优化方案 1.1. 2.1相关知识点介绍 1.1. 2.1.1Oracle的硬解析和软解析 Oracle对sql的处理过程:当发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行几个步骤的处理过程: 1、语法检查(syntax check) 检查此sql的拼写是否语法。 2、语义检查(semantic check) 诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。 3、对sql语句进行解析(prase) 利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。 4、执行sql,返回结果(execute and return) 其中,软、硬解析就发生在第三个过程里。 Oracle利用内部的hash算法来取得该sql的hash值,然后在library cache

mysql服务性能优化my_cnf配置说明详解16G内存

mysql服务性能优化—https://www.360docs.net/doc/579528510.html,f配置说明详解 (16G内存) MYSQL服务器https://www.360docs.net/doc/579528510.html,f配置文档详解 硬件:内存16G [client] port = 3306 socket = /data/3306/mysql.sock [mysql] no-auto-rehash [mysqld] user = mysql port = 3306 socket = /data/3306/mysql.sock basedir = /usr/local/mysql datadir = /data/3306/data open_files_limit = 10240 back_log = 600 #在MYSQL暂时停止响应新请求之前,短时间内的多少个请求可以被存在堆栈中。如果系统在短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的监听队列的大小。默认值50。 max_connections = 3000 #MySQL允许最大的进程连接数,如果经常出现Too Many Connections的错误提示,则需要增大此值。 max_connect_errors = 6000 #设置每个主机的连接请求异常中断的最大次数,当超过该次数,MYSQL服务器将禁止host 的连接请求,直到mysql服务器重启或通过flush hosts命令清空此host的相关信息。 table_cache = 614 #指示表调整缓冲区大小。# table_cache 参数设置表高速缓存的数目。每个连接进来,都会至少打开一个表缓存。#因此, table_cache 的大小应与 max_connections 的设置有关。例如,对于 200 个#并行运行的连接,应该让表的缓存至少有 200 × N ,这里 N 是应用可以执行的查询#的一个联接中表的最大数量。此外,还需要为临时表和文件保留一些额外的文件描述符。 # 当 Mysql 访问一个表时,如果该表在缓存中已经被打开,则可以直接访问缓存;如果#还

大数据库优化(SQLServer)

SQL SERVER性能优化综述 近期因工作需要,希望比较全面的总结下SQL SERVER数据库性能优化相关的注意事项,在 网上搜索了一下,发现很多文章,有的都列出了上百条,但是仔细看发现,有很多似是而非或 者过时(可能对SQL SERVER6.5以前的版本或者ORACLE是适用的)的信息,只好自己根据以 前的经验和测试结果进行总结了。 我始终认为,一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的。所以我希望按照软件生命周期的不同阶段来总结数据库性能优化相关的注意事项。 一、分析阶段 一般来说,在系统分析阶段往往有太多需要关注的地方,系统各种功能性、可用性、可靠性、安全性需求往往吸引了我们大部分的注意力,但是,我们必须注意,性能是很重要的非功能 性需求,必须根据系统的特点确定其实时性需求、响应时间的需求、硬件的配置等。最好能 有各种需求的量化的指标。 另一方面,在分析阶段应该根据各种需求区分出系统的类型,大的方面,区分是OLTP(联机事务处理系统)和OLAP(联机分析处理系统)。 二、设计阶段 设计阶段可以说是以后系统性能的关键阶段,在这个阶段,有一个关系到以后几乎所有性能 调优的过程—数据库设计。 在数据库设计完成后,可以进行初步的索引设计,好的索引设计可以指导编码阶段写出高效 率的代码,为整个系统的性能打下良好的基础。 以下是性能要求设计阶段需要注意的: 1、数据库逻辑设计的规范化 数据库逻辑设计的规范化就是我们一般所说的范式,我们可以这样来简单理解范式: 第1规范:没有重复的组或多值的列,这是数据库设计的最低要求。 第2规范: 每个非关键字段必须依赖于主关键字,不能依赖于一个组合式主关键字的某些组 成部分。消除部分依赖,大部分情况下,数据库设计都应该达到第二范式。 第3规范: 一个非关键字段不能依赖于另一个非关键字段。消除传递依赖,达到第三范式应该是系统中大部分表的要求,除非一些特殊作用的表。 更高的范式要求这里就不再作介绍了,个人认为,如果全部达到第二范式,大部分达到第三

大型数据库的优化方法及实例

大型数据库的优化方法及实例 尹德明杨富玉杨莹时鹏泉 中国金融电子化公司 E_mail: dm_mis@https://www.360docs.net/doc/579528510.html, 1.引言 随着银行业数据集中,作为整个系统核心的数据库,其存放、管理的数据越来越庞大,已经超越GB而到达TB数据量层次,数据库的性能成为整个系统性能的关键。 国库会计核算系统是国库部门用以进行国库业务的会计核算,并通过支付系统、国库内部往来、同城票据交换系统进行资金清算的计算机网络系统。国家金库会计核算系统每天处理的税票数据多达10万笔,税收高峰可能会到100万笔,这样一年累计下来其中历史登记簿中的数据达到2000万条以上,给检索和数据处理带来非常大的困难。 如何对于一个已经上线运行的重要业务系统,通过对数据库的优化和简单的系统流程调整,实现系统性能的大幅提升具有现实、迫切、重要的意义。 2.优化策略 根据Sybase的数据存储机制,在进行一段时期的数据删除、插入和更新等操作后,数据库往往会产生大量的碎片。大量碎片的存在,会严重影响数据库的I/O性能,如果在使用数据库一段时间后,整理碎片,可以提高数据库的性能。由于国家金库会计核算系统在预处理、日间报解、日初始化等步骤,会大批量进行数据删除、插入和更新等操作,因此会产生大量的数据碎片。碎片整理对于国家金库会计核算系统性能优化将会有重要效果。 Sybase Adaptive Server对于按顺序存储和访问的页,在单个I/O中最多读取八个数据页。由于大部分I/O时间都花在磁盘上的物理定位和搜寻上,因此大I/O可极大地减少磁盘访问时间。在大多数情况下,希望在缺省数据高速缓存中配置一个16K缓冲池。为事务日志创建4K缓冲池可极大地减少数据库系统日志写操作的数量。 好的性能同优良的数据库设计及优秀的程序写法关系极大,可以这样说,如果一个数据库没有好的设计及对程序未进行优化的话即使对参数进行调整也不可能有好的性能。 3.数据库碎片整理 由于Sybase是通过OAM页、分配单元和扩展页来管理数据的,所以对OLTP应用的Database Server会十分频繁地进行数据删除、插入和更新等操作,时间一长就会出现以下几种情况: (1)页碎片 即本来可以存放在一个页上的数据却分散地存储在多个页上。如果这些页存储在不同的扩展单元上,Database Server就要访问多个扩展单元,因此降低了系统性能。 (2)扩展单元碎片 在堆表中,当删除数据链中间的记录行时,会出现空页。随着空页的累积,扩展单元的利用率也会下降,从而出现扩展单元碎片。带cluster index的table也有可能出现扩展单元碎片。当有扩展单元碎片存在,会出现以下问题: 对表进行处理时,常常出现死锁;利用较大的I/O操作或增加I/O缓冲区的大小也无法改变较慢的I/O速度;行操作的争用。 (3)扩展单元遍历 带有cluster index的table会由于插入记录而导致页分裂,但当删除记录后,页会获得释放,从而形成跨几个扩展单元和分配单元的数据,而要访问该数据就必须遍历几个扩展单元和分配单元。这将导致访问/查询记录的时间大大延长,开始时数据库的性能虽然较高,

谈谈项目中常用的MySQL优化方法

谈谈项目中常用的MySQL优化方法 本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 一、EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划。 下面来个简单的示例,标注(1、2、3、4、5)我们要重点关注的数据: type列,连接类型。一个好的SQL语句至少要达到range级别。杜绝出现all级别。 key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式 key_len列,索引长度。 rows列,扫描行数。该值是个预估值。 extra列,详细说明。注意,常见的不太友好的值,如下:Using filesort,Using temporary。 二、SQL 语句中IN 包含的值不应过多 MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from t where num in(1,2,3) 对于连续的数值,能用between就不要用in了;再或者使用连接来替换。 三、SELECT语句务必指明字段名称 SELECT*增加很多不必要的消耗(CPU、IO、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。 四、当只需要一条数据的时候,使用limit 1 这是为了使EXPLAIN中type列达到const类型 五、如果排序字段没有用到索引,就尽量少排序 六、如果限制条件中其他字段没有索引,尽量少用or or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时候)的方式来代替“or”

SQL Server数据库优化方案汇总

SQL Server数据库优化方案汇总 50种方法优化SQL Server 1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2、I/O吞吐量小,形成了瓶颈效应。 3、没有创建计算列导致查询不优化。 4、内存不足 5、网络速度慢 6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。 9、返回了不必要的行和列 10、查询语句不好,没有优化 可以通过如下方法来优化查询 : 1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要. 2、纵向、横向分割表,减少表的尺寸(sp_spaceuse) 3、升级硬件 4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使 用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段 5、提高网速; 6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行 配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算 运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。 7、增加服务器 CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成 多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并 行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作Update,Insert, Delete还不能并行处理。 8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。 9、DB Server 和APPLication Server 分离;OLTP和OLAP分离

MySQL5.1性能优化方案

MySQL5.1性能优化方案 1.平台数据库 1.1.操作系统 Red Hat Enterprise Linux Server release 5.4 (Tikanga) ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped 32位Linux服务器,单独作为MySQL服务器使用。 1.2.M ySQL 系统使用的是MySQL5.1,最新的MySQL5.5较之老版本有了大幅改进。主要体现在以下几个方面: 1)默认存储引擎更改为InnoDB InnoDB作为成熟、高效的事务引擎,目前已经广泛使用,但MySQL5.1之前的版本默认引擎均为MyISAM,此次MySQL5.5终于将默认数据库存储引擎改为InnoDB,并且引进了Innodb plugin 1.0.7。此次更新对数据库的好处是显而易见的:InnoDB的数据恢复时间从过去的一个甚至几个小时,缩短到几分钟(InnoDB plugin 1.0.7,InnoDB plugin 1.1,恢复时采用红-黑树)。InnoDB Plugin 支持数据压缩存储,节约存储,提高内存命中率,并且支持adaptive flush checkpoint, 可以在某些场合避免数据库出现突发性能瓶颈。 Multi Rollback Segments:原来InnoDB只有一个Segment,同时只支持1023的并发。现已扩充到128个Segments,从而解决了高并发的限制。 2)多核性能提升

SQL数据库优化方法

SQL数据库优化方法

目录 1 系统优化介绍 (1) 2 外围优化 (1) 3 SQL优化 (2) 3.1 注释使用 (2) 3.2 对于事务的使用 (2) 3.3 对于与数据库的交互 (2) 3.4 对于SELECT *这样的语句, (2) 3.5 尽量避免使用游标 (2) 3.6 尽量使用count(1) (3) 3.7 IN和EXISTS (3) 3.8 注意表之间连接的数据类型 (3) 3.9 尽量少用视图 (3) 3.10 没有必要时不要用DISTINCT和ORDER BY (3) 3.11 避免相关子查询 (3) 3.12 代码离数据越近越好 (3) 3.13 插入大的二进制值到Image列 (4) 3.14 Between在某些时候比IN 速度更快 (4) 3.15 对Where条件字段修饰字段移到右边 (4) 3.16 在海量查询时尽量少用格式转换。 (4) 3.17 IS NULL 与IS NOT NULL (4) 3.18 建立临时表, (4) 3.19 Where中索引的使用 (5) 3.20 外键关联的列应该建立索引 (5) 3.21 注意UNion和`UNion all 的区别 (5) 3.22 Insert (5) 3.23 order by语句 (5) 3.24 技巧用例 (6) 3.24.1 Sql语句执行时间测试 (6)

1系统优化介绍 在我们的项目中,由于客户的使用时间较长或客户的数据量大,造成系统运行速度慢,系统性能下降就容易造成数据库阻塞。这是个非常痛苦的事情,用户的查询、新增、修改等需要花很多时间,甚至造成系统死机的现象。速度慢的原因主要是来自于资源不足。 数据库的优化通常可以通过对网络、硬件、操作系统、数据库参数和应用程序的优化来进行。最常见的优化手段就是对硬件的升级。根据统计,对网络、硬件、操作系统、数据库参数进行优化所获得的性能提升,全部加起来最多只占数据库系统性能提升的40%左右(我将此暂时称之为外围优化);其余大部分系统性能提升来自对应用程序的优化,对于应用程序的优化可以分为对源代码的优化及数据库SQL语句的优化。在本文档只介绍外围优化及SQL语句的优化,对于源代码的优化需要相关方面的专家,形成统一的规范。 一个数据库系统的生命周期可以分成:设计、开发和成品三个阶段。在设计阶段进行数据库性能优化的成本最低,收益最大。在成品阶段进行数据库性能优化的成本最高,收益最小。规范的代码和高性能的语句,功在平时,利在千秋。 2外围优化 1、将操作系统与SQL数据库的补丁打到最高版本,WIN2003最高补丁是SP4, SQL SERVER2000最高补丁是SP4(版本号:2039)。 2、在服务器上不要安装与VA程序任何无相关的软件,甚至一些与VA运行 无关的服务都可以停掉。一般只安装SQL数据库、VA服务端服务及杀毒 软件。 3、杀毒软件避免对大文件进行扫描,特别是数据库(MDF和LDF)文件,一 定要从杀毒软件的范围内排除掉。 4、在进行服务器分区时,分区不要太多,两三个分区就可以了。分区最好 都使用NTFS格式。

MySQL优化原则

MySQL优化原则 转载2014年05月20日10:27:13 1113 数据库已成为互联网应用必不可少的底层依赖,其中MySQL作为开源数据库得到了更加广泛的应用。最近一直专注于项目工程的开发,对开发过程中使用到的一些关于数据库的优化原则进行了总结,希望能够帮助更多的应用开发人员更好的使用MySQL数据库。 MySQL的优化主要包括三个方面,首先是SQL语句的优化,其次是表结构的优化,这里主要指索引的优化,最后是服务器配置的优化。第四点代码结构的优化!!! 1.SQL语句的优化 1)查询语句应该尽量避免全表扫描,首先应该考虑在Where子句以及OrderBy子句上建立索引,但是每一条SQL语句最多只会走一条索引,而建立过多的索引会带 来插入和更新时的开销,同时对于区分度不大的字段,应该尽量避免建立索引,可 以在查询语句前使用explain关键字,查看SQL语句的执行计划,判断该查询语 句是否使用了索引; 2)应尽量使用EXIST和NOT EXIST代替 IN和NOT IN,因为后者很有可能导致全表扫描放弃使用索引; 3)应尽量避免在Where子句中对字段进行NULL判断,因为NULL判断会导致全表扫描; 4)应尽量避免在Where子句中使用or作为连接条件,因为同样会导致全表扫描; 5)应尽量避免在Where子句中使用!=或者<>操作符,同样会导致全表扫描; 6)使用like “%abc%”或者like “%abc”同样也会导致全表扫描,而like “abc%”会使用索引。 7)在使用Union操作符时,应该考虑是否可以使用Union ALL来代替,因为Union 操作符在进行结果合并时,会对产生的结果进行排序运算,删除重复记录,对于没

数据库优化设计方案

数据库优化方案设计 XX信息管理平台从大型数据库环境四个不同级别的调整分析入手,分析数据库平台的系统结构和工作机理,从九个不同方面设计数据库的优化方案。 对于数据库的数据优化,主要有四个不同的调整级别,第一级调整是操作系统级包括硬件平台,第二级调整是RDBMS级的调整,第三级是数据库设计级的调整,最后一个调整级是SQL级。通常依此四级调整级别对数据库进行调整、优化,数据库的整体性能会得到很大的改善。下面从九个不同方面介绍数据库优化设计方案。 一、数据库优化自由结构 数据库的逻辑配置对数据库性能有很大的影响。为此,数据库平台一般对表空间设计提出有相应的优化结构,如ORACLE公司的OFA(Optimal flexible Architecture),使用这种结构进行设计会大大简化物理设计中的数据管理。优化自由结构,简单地讲就是在数据库中可以高效自由地分布逻辑数据对象,因此首先要对数据库中的逻辑对象根据他们的使用方式和物理结构对数据库的影响来进行分类,这种分类包括将系统数据和用户数据分开、一般数据和索引数据分开、低活动表和高活动表分开等等。 数据库逻辑设计的结果应当符合下面的准则: (1)把以同样方式使用的段类型存储在一起; (2)按照标准使用来设计系统; (3)存在用于例外的分离区域; (4)最小化表空间冲突; (5)将数据字典分离。 二、充分利用系统全局区域 系统全局区域是数据库平台的心脏,如Oracle数据库的SGA(SYSTEM GLOBAL AREA) 。用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的。正确的SGA大小对数据库的性能至关重要。SGA包括以下几个部分: 1、数据块缓冲区(data block buffer cache)是SGA中的一块高速缓存,占整个数据库大小的1%-2%,用来存储从数据库重读取的数据块(表、索引、簇等),因此采用least recently used (LRU,最近最少使用)的方法进行空间管理。 2、字典缓冲区。该缓冲区内的信息包括用户账号数据、数据文件名、段名、盘区位置、表说明和权限,它也采用LRU方式管理。 3、重做日志缓冲区。该缓冲区保存为数据库恢复过程中用于前滚操作。 4、SQL共享池。保存执行计划和运行数据库的SQL语句的语法分析树。也采用LRU 算法管理。如果设置过小,语句将被连续不断地再装入到库缓存,影响系统性能。 另外,SGA还包括大池、JAVA池、多缓冲池。但是主要是由上面4种缓冲区构成。对这些内存缓冲区的合理设置,可以大大加快数据查询速度,一个足够大的内存区可以把绝大多数数据存储在内存中,只有那些不怎么频繁使用的数据,才从磁盘读取,这样就可以大大提高内存区的命中率。 三、规范与反规范设计数据库

千万级的mysql数据库与优化方法

千万级的mysql数据库与优化方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引。 2.应尽量避免在where 子句中对字段进行null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: Sql代码 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: Sql代码 3.应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 4.应尽量避免在where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:Sql代码 可以这样查询: Sql代码 5.in 和not in 也要慎用,否则会导致全表扫描,如: 对于连续的数值,能用between 就不要用in 了: 6.下面的查询也将导致全表扫描: Sql代码

若要提高效率,可以考虑全文检索。 7.如果在where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描: Sql代码 可以改为强制查询使用索引: 8.应尽量避免在where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: 应改为: 9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:Sql代码 应改为: 10.不要在where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。 11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。 12.不要写一些没有意义的查询,如需要生成一个空表结构:

大型ORACLE数据库优化设计方案

大型ORACLE数据库优化设计方案 摘要主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案。 关键词ORACLE数据库环境调整优化设计方案 对于ORACLE数据库的数据存取,主要有四个不同的调整级别,第一级调整是操作系统级包括硬件平台,第二级调整是ORACLERDBMS级的调整,第三级是数据库设计级的调整,最后一个调整级是SQL级。通常依此四级调整级别对数据库进行调整、优化,数据库的整体性能会得到很大的改善。下面从九个不同

方面介绍ORACLE数据库优化设计方案。 一.数据库优化自由结构OFA(OptimalflexibleArchitecture) 数据库的逻辑配置对数据库性能有很大的影响,为此,ORACLE公司对表空间设计提出了一种优化结构OFA。使用这种结构进行设计会大大简化物理设计中的数据管理。优化自由结构OFA,简单地讲就是在数据库中可以高效自由地分布逻辑数据对象,因此首先要对数据库中的逻辑对象根据他们的使用方式和物理结构对数据库的影响来进行分类,这种分类包括将系统数据和用户数据分开、一般数据和索引数据分开、低活动表和高活动表分开等等。 二、充分利用系统全局区域SGA (SYSTEMGLOBALAREA) SGA是oracle数据库的心脏。用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的。正确的SGA大小对数据库

的性能至关重要。SGA包括以下几个部分: 2、字典缓冲区。该缓冲区内的信息包括用户账号数据、数据文件名、段名、盘区位置、表说明和权限,它也采用LRU 方式管理。 3、重做日志缓冲区。该缓冲区保存为数据库恢复过程中用于前滚操作。 4、SQL共享池。保存执行计划和运行数据库的SQL语句的语法分析树。也采用LRU算法管理。如果设置过小,语句将被连续不断地再装入到库缓存,影响系统性能。 另外,SGA还包括大池、JA V A池、多缓冲池。但是主要是由上面4种缓冲区构成。对这些内存缓冲区的合理设置,可以大大加快数据查询速度,一个足够大的内存区可以把绝大多数数据存储在内存中,只有那些不怎么频繁使用的数据,才从磁盘读取,这样就可以大大提高内存区的命中率。三、规范与反规范设计数据库

数据库查询优化实验报告_SQLServer2008

SQL Server 2008数据查询的优化方法研究摘要 随着数据存储需求的日益增长,对关系数据的管理和访问就成为数据库技术必须解决的问题。本文主要论述关系数据库查询优化技术,并从它的优化技术进行深入探讨,对系统实现做了一定的论述,并进行了部分的程序实现。 关键词:数据库查询系统优化 引言 SQLServer是是由微软公司开发的基于Windows操作系统的关系型数据库管理系统,它是一个全面的、集成的、端到端的数据解决方案,为企业中的用户提供了一个安全、可靠和高效的平台用于企业数据管理和商业智能应用。目前,许多中小型企业的数据库应用系统都是用SQLServer作为后台数据库管理系统设计开发的。设计一个应用系统并不难,但是要想使系统达到最优化的性能并不是一件容易的事。根据多年的实践,由于初期的数据库中表的记录数比较少,性能不会有太大问题,但数据积累到一定程度,达到数百万甚至上千万条,全面扫描一次往往需要数十分钟,甚至数小时。20%的代码用去了80%的时间,这是程序设计中的一个著名定律,在数据库应用程序中也同样如此。如果用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟。而且我们知道,目前数据库系统应用中,查询操作占了绝大多数,查询优化成为数据库性能优化最为重要的手段之一。 影响查询效率的因素 SQLServer处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给SQLServer的查询优化器,查询优化器通过检查索引的存在性、有效性和基于列的统计数据来决定如何处理扫描、检索和连接,并生成若干执行计划,然后通过分析执行开销来评估每个执行计划,从中选出开销最小的执行计划,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。所以,SQLServer中影响查询效率的因素主要有以下几种: 1.没有索引或者没有用到索引。索引是数据库中重要的数据结构,使用索引的目的是避免全表扫描,减少磁盘I/O,以加快查询速度。 2.没有创建计算列导致查询不优化。 3.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。 4.返回了不必要的行和列。 5.查询语句不好,没有优化。其中包括:查询条件中操作符使用是否得当;查询条件中的数据类型是否兼容;对多个表查询时,数据表的次序是否合理;多个选择条件查询时,选择条件的次序是否合理;是否合理安排联接选择运算等。 SQLServer数据查询优化方法 1、避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary 是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如: select name from employee where salary >60000

Mysql千万级别数据优化方案总结

Mysql千万级别数据优化方案 目录 目录 (1) 一、目的与意义 (2) 1)说明 (2) 二、解决思路与根据(本测试表中数据在千万级别) (2) 1)建立索引 (2) 2)数据体现(主键非索引,实际测试结果其中fid建立索引) (2) 3)MySQL分页原理 (2) 4)经过实际测试当对表所有列查询时 (2) 三、总结 (3) 1)获得分页数据 (3) 2)获得总页数:创建表记录大数据表中总数通过触发器来维护 (3)

一、目的与意义 1)说明 在MySql单表中数据达到千万级别时数据的分页查询结果时间过长,对此进行优达 到最优效果,也就是时间最短;(此统计利用的jdbc连接,其中fid为该表的主键;) 二、解决思路与根据(本测试表中数据在千万级别) 1)建立索引 优点:当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜 索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记 录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;第二种就是 在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索 引中的ROWID(相当于页码)快速找到表中对应的记录。 缺点:当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降 低了数据的维护速度。 2)数据体现(主键非索引,实际测试结果其中fid建立索引) 未创建索引:SELECT fid from t_history_data LIMIT 8000000,10结果:13.396s 创建索引:SELECT fid from t_history_data LIMIT 8000000,10结果:2.896s select*fromt_history_datawherefidin (任意十条数据的id )结果:0.141s 首先通过分页得到分页的数据的ID,将ID拼接成字符串利用SQL语句 select * from table where ID in (ID字符串)此语句受数据量大小的影响比较小 (如上测试); 3)MySQL分页原理 MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要 的,所以n越大,性能会越差。 优化前SQL: SELECT * FROM v_history_data LIMIT 5000000, 1010.961s 优化后SQL: SELECT * FROM v_history_data INNER JOIN (SELECT fid FROM t_history_data LIMIT 5000000, 10) a USING (fid)1.943s 分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后 抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了, 然后通过member_id读取需要的列 4)经过实际测试当对表所有列查询时 select * from table 会比select (所有列名)from table 快些(以查询8000000

优化MySQL数据库性能的几个好方法

1、选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。 另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。 对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。这样,我们又可以提高数据库的性能。 2、使用连接(JOIN)来代替子查询(Sub-Queries) MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来,然后将结果传递给主查询,如下所示: DELETE FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo ) 使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询可以被更有效率的连接(JOIN).. 替代。例如,假设我们要将所有没有订单记录的用户取出来,可以用下面这个查询完成:

数据库优化查询计划的方法

数据库优化查询计划的方法 数据库系统是管理信息系统的核心,基于数据库的联机事务处理(OLTP)以及联机分析处理(OLAP)是银行、企业、政府等部门最为重要的计算机应用之一。从大多数系统的应用实例来看,查询操作在各种数据库操作中所占据的比重最大,而查询操作所基于的SELECT语句在SQL语句中又是代价最大的语句。举例来说,如果数据的量积累到一定的程度,比如一个银行的账户数据库表信息积累到上百万甚至上千万条记录,全表扫描一次往往需要数十分钟,甚至数小时。如果采用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟,由此可见查询优化技术的重要性。 在应用项目的实施中发现,许多程序员在利用一些前端数据库开发工具(如PowerBuilder、Delphi等)开发数据库应用程序时,只注重用户界面的华丽,并不重视查询语句的效率问题,导致所开发出来的应用系统效率低下,资源浪费严重。因此,如何设计高效合理的查询语句就显得非常重要。本文以应用实例为基础,结合数据库理论,介绍查询优化技术在现实系统中的运用。 分析问题 许多程序员认为查询优化是DBMS(数据库管理系统)的任务,与程序员所编写的SQL语句关系不大,这是错误的。

一个好的查询计划往往可以使程序性能提高数十倍。查询计划是用户所提交的SQL语句的集合,查询规划是经过优化 处理之后所产生的语句集合。DBMS处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给DBMS的查询优化器,优化器做完代数优化和存取路径的优化之后,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。在实际的数据库产品(如Oracle、Sybase等)的高版本中都是采用基于代价的优化方法,这种优化能根据从系统字典表所得到的信息来估计不同的查询规划的代价,然后选择一个较优的规划。虽然现在的数据库产品在查询优化方面已经做得越来越好,但由用户提交的SQL语句是系统优 化的基础,很难设想一个原本糟糕的查询计划经过系统的优化之后会变得高效,因此所写语句的优劣至关重要。下面重点说明改善查询计划的解决方案。 解决问题 下面以关系数据库系统Informix为例,介绍改善用户查询计划的方法。 1.合理使用索引 索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如

相关文档
最新文档