存档

文章标签 ‘数据库’

Mysql的排序机制

2010年5月1日 admin 没有评论

在查mysql的排序问题时, 了解了一下Mysql的排序机制, 大体是:

mysql把需要排序的地方都叫filesort, 名字上看有个file在里面,但不一定与文件有关, 可能就是在内存完成的排序。

MySQL 有二个 filesort 算法, 第一个方法(原始方法)只使用了ORDER BY中指定的字段。第二个方法(改进的方法)不仅使用ORDER BY中指定的字段,还是用了查询中所涉及到的所有的字段。

优化器决定选择哪个filesort 算法, 除了查询中涉及到TEXT或者BLOCk字段外,它通常使用改进的算法,当查询中涉及到TEXT或者BLOCk字段时,通常使用原始的方法。

原始的 filesort 算法的工作机制大体是(典型的外排算法):

阅读全文…

相关日志

分类: MySQL 标签: , , , ,

Mysql主从同步延迟受到机器系统时间的影响

2010年4月30日 admin 没有评论

Mysql主从同步延迟受到多种因素影响, 比如大事务, 从库查询压力, 网路延迟等; 这些比较常见; 但还受到主从机器系统时钟差的影响,这一点可能容易被忽视。

上周, 就遇到了这样的情况, 主库的系统时间由于某种原因落后于从库几十秒, 结果频繁的出现大的主从延迟同步 ,查了N久业务方面的问题, 都找不出原因; 在和同事的交流中,发现大家对参数Seconds_Behind_Master的理解有点补一样,基本有两种理解:

一种理解是来源于Mysql手册上的描述, 大体意思是这个时间是从库SQL线程处理的最近的日志事件的时间戳减去从库IO线程处理的最近一条日志记录的时间戳得到的, 可以简单理解为从库SQL线程与IO线程所处理的最近的日志事件的时间戳差;这个计算方式给人的感觉不是在计算主从延迟,而是在计算从库上两个线程的处理 的日志的时差。

阅读全文…

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (十)

2010年4月28日 admin 没有评论

Bit-Packed Data Types

MySQL有一些存储类型使用一个值中的一些单个的比特位来紧凑的存储数据。纯技术上将,不管是底层的存储格式还是操作,所有这些类型都是字符串类型。

BIT

MySQL5.0以前, BIT只是TINYINT的同义词而已。但是在MySQL5.0以及之后的版本,BIT是一个完全不同的数据类型了, 有着自己的一些特点, 这里讨论一些新的行为和属性:

可以用BIT字段在单列里面来存储一个或多个true/false值, BIT(1)定义一个了只包含单个比特位的字段, BIT(2)是存储2个比特位的字段, 如此类推;BIT字段的最大长度可以是64个比特。

BIT类型的行为与存储引擎有关。MyISAM把一些列为了存储的目的打包到一起, 所以17个单独的BIT列需要17个比特来存储(假定这些列都不允许NULL),MyISAM会近似算成3个字节来存储。其他的一些存储引擎, 比如Memory和InnoDB, 把每个列都用有足够长度存储这些比特位的最小整数来存储,所以无法节省存储空间。

* TIMESTAMP类型的一些行为的规则比较复杂并随着不同的MySQL版本而变化,所以在使用时应当确认是自己所期望的行为。通常, 在对TIMESTAMP的列做了改变后通过查看SHOW CREATE TABALE的结果来确认是一个的主意。

MySQL把BIT当做字符串类型, 而不是数据类型。当检索BIT(1)列的值, 结果是一个字符串而内容是二进制位0或1, 而不是ASCII值”0″或”1″.然而, 如果在一个数值上下文检索的话, 结果是比特串转化而成的数字。 当需要与另一个值进行比较时, 记住这一点。比如, 如果存储值’00111001′(是57的二进制表示)到一个BIT(8)的字段中然后检索出来,得到的是字符编码值为57字符串, 而这值就是“9”的ASCII编码。但是在数值环境中, 得到的是值57:s

阅读全文…

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (九)

2010年4月27日 admin 没有评论

日期和时间类型

MySQL有多个表示各种日期和时间值的数据类型, 比如YEAR和DATE. MySQL存储时间的最精确粒度是秒。 然而, 能做微妙粒度的临时计算, 我们会列出一些绕过存储引擎限制的一些方法。

许多时间类型都没有可替换类型, 因而不存在什么是最佳选择这么一说。 唯一的问题是当需要一起存储日期和时间时如何做?MySQL提供了两个非常类似的数据类型来做这个事情: DATETIME和TIMESTAMP. 多大多数应用来说, 两个都行, 但是在某些场合, 一个可能比另一个更合适:

DATETIME

这个类型能够存储很大范围的值, 从1001年到9999年, 准确到秒的精度。它把日期和时间打包成整数以YYYYMMDDHHMMSS 格式表示, 与时区无关。用8个字节的存储空间。

缺省情况下, MySQL以可排序,无歧义的格式显示DATETIME值, 比如 2008-01-16 22:37:08, 这是ANSI下标准显示日期时间的方式。

TIMESTAMP

如名字所指出的,TIMESTAMP 类型存储从1970年1月1日(格林威治时间)到目前为止经过的秒数 –与UNIX时间戳一样。TIMESTAMP 使用4个字节来存储值, 所能表示的范围以比DATETIME要小: 从1970年到2038年。MySQL提供了 FROM_UNIXTIME( ) 和 UNIX_TIMESTAMP( ) 两个函数来进行Unix时间戳与日期类型的相互转换。

新版本的MySQL中TIMESTAMP 采用了与DATETIME 一样的格式来表示值,但是老版本的MySQL没有在各个部分件显示分隔符。 这只是一个显示格式的区别而已,TIMESTAMP 的存储格式在各个版本与DATETIME一致。

TIMESTAMP 对值的显示与时区相关,MySQL服务器,操作系统和客户端连接都有相应的时区设置。

因此,对于与GMT有5个小时时差的东部时间,一个值为0的TIMESTAMP 类型实际显示的内容可能会是1969-12-31 19:00:00。

TIMESTAMP 也有一些DATETIME所不具备的一些属性。 缺省情况下, 插入记录时,MySQL会把第一个没指定具体值得TIMESTAMP 类型的字段自动设置为当前值,在修改时, 如果没有在修改语句中显式的指定值, 第一个DATESTAMP类型的字段的值也会被更行为当前值。也可以通过配置修改修改和插入记录时对TIMESTAMP 列的处理行为。最后, TIMESTAMP列缺省不为NULL, 这与其他数据类型不一样。

除了一些特殊行为,在一般情况下,如果能够使用TIMESTAMP,就使用它, 因为它比DATETIME的空间效率要高。有时候,有人把Unix时间戳存储成整数, 但是实际上没有任何好处,因为格式转换很不方便,我们不推荐这么做。

如果需要存储比秒精度更高的日期和时间数据怎么办呢?MySQL当前并没有提供合适的数据类型, 但是可以根据需要选择自己的存储格式:可以使用BIGINT类型存储毫秒精度的数据,或者使用DOUBLE类型,把秒后面的数值当做小数点后面的小数部分。 这两种方法都不错。

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (八)

2010年4月26日 admin 没有评论

使用ENUM代替字符串类型

有时候, 可以通过使用ENUM来代理常规的字符串类型。一个ENUM列能够存储65535个不同的字符串值,MySQL非常紧凑的存储这些值,会根据值列表把这些值存储到1到2个字节中。通过在表的.frm文件中保存一个数字到字符串的对应关系来保存一个”查询表”, 它把每个值存储成一个表示值在字段定义列表中的某个位置的整数。 下面是几个例子;

mysql> CREATE TABLE enum_test(

-> e ENUM(‘fish’, ‘apple’, ‘dog’) NOT NULL

-> );

mysql> INSERT INTO enum_test(e) VALUES(‘fish’), (‘dog’), (‘apple’);

这3列实际上存储的是整数, 而不是字符串。 能够通过在数字检索上下文中查看到这些值的两面属性:

阅读全文…

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (七)

2010年4月25日 admin 没有评论

如何避免磁盘临时表

因为内存储引擎不支持TEXT和BLOB数据类型, 使用到BLOB和TEXT列的查询和使用隐式临时表的查询将不得不使用MyISAM的磁盘临时表, 即使只有很少的几条记录。 这可能导致很严重的性能开销。即使把MySQL配置成在RAM盘上使用临时表, 也会用到一些开销大的系统调用(Maria存储引擎应该能通过把所有的东西, 而不只是索引,缓存在内存中而在一定程度上缓解这个问题)。最好的解决办法是避免使用BLOB和TEXT类型, 除非费用不可。

.

如果无法避免使用BLOB和TEXT类型, 应该能够通过使用ORDER BY SUBSTRING(column, length)

的办法来把这些类型的值转化成字符串,这样不会妨碍使用内存临时表。另外, 确认一下的所使用的子串的长度是否短到不会导致临时表的大小不会超过 max_heap_table_size 或 tmp_table_size, 否则,还是会生成MyISAM的磁盘临时表。

如果EXPLAIN结果中的”Extra”列里面包含”Using temporary”, 那么查询会使用一个隐式的临时表。

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (六)

2010年4月24日 admin 没有评论

BINARY和VARBINARY

数据的存储是存储引擎相关的, 并不是所有的存储引擎用同样的方式来处理定长和变长类型。Memory存储引擎使用定长的行, 因而它分配尽可能多的空间给变长字段来存储数据。 而Falcon则使用变长字段来存储, 即使对于CHAR字段也是如此。 但是填充和去尾是一致de 这是因为这个是由MySql服务器自己处理的。

CHAR和VCHAR的兄弟类型分别是存储二进制数据的BINARY和VARBINARY, 二进制字符串与普通的字符长相似, 不过他们是以字节存储的, 而不是字符,填充也不一样 , Mysql用\0(0 字节)而不是空格填充二进制数据, 而在检索时不会把后面的填充值去掉。

对于需要存数二进制数据的活着需要Mysql对值进行字节的比较而不是基于字符的比较时, 二进制数据类型非常有用。基于字节的比较的优势不只是大小写不敏感的好处, Mysql在比较二进制数据时, 通过字节表示的数值比较的方式进行的, 因为二进制数据相对与基于字符的比较更简单, 也更快。

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (五)

2010年4月23日 admin 没有评论

当存储一个CHAR值时, Mysql会除去尾随空间, 这个行为有点让人困惑, 用一个具体的例子来看一下: 首先 ,创建一个只有一个CHAR(10)字段的表并存储一些值在里面:

mysql> CREATE TABLE char_test( char_col CHAR(10));

mysql> INSERT INTO char_test(char_col) VALUES

-> (’string1′), (‘ string2′), (’string3 ‘);

然后检索这些值, 尾部空间被除掉了:

mysql> SELECT CONCAT(“‘”, char_col, “‘”) FROM char_test;

+—————————-+

| CONCAT(“‘”, char_col, “‘”) |

+—————————-+

| ’string1′ |

| ‘ string2′ |

| ’string3′ |

+—————————-+

阅读全文…

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (四)

2010年4月22日 admin 没有评论

String Types(字符串类型)

字符串类型

Mysql支持多种字符串类型的变体。 这些数据类型在4.1和5.0版本中有较大的变化, 这使得这些数据类型变得更加复杂。 从Mysql4.1起, 每个字符串类型能有自己的字符集和针对这些字符集的排序规则集 (更多的关于排序规则的主题, 参考第5章), 这对于性能有较大的影响。

VARCHAR和CHAR类型

VARCHAR和CHAR是两种最主要的存储字符串的数据类型, 不幸的是,的确有些困难解释这两种数据类型在磁盘和内存中是如何存储的, 因为这是与存储引擎相关的(比如, Falcon的差不多所有数1是, 请参考相应的存储引擎文档。

阅读全文…

相关日志

分类: MySQL 标签: , ,

MySQL表设计优化与索引 (三)

2010年4月21日 admin 没有评论

Real Numbers

实数

实数是具有小数部分的数字, 当然, 实数不是专门用来表示小数的, 也可以用DECIMAL来存储那些无法用INTERGER来存储的大整数。 Mysql同时支持准确的和非准确的类型。

FLOAT和DOUBLE类型支持近似的标准浮点数数学计算。 如果需要知道准确的浮点数计算, 参考具体平台的浮点数计算规则。

DECIMAL类型是用来存储准确的小数, 在mysql 5.0以后的版本, DECIMAL支持准确的数学计算。在Mysql4.1 及以前的版本中, MUMERIC类型也是用浮点计算来完成运算的, 因此可能会出现一些由于精度损失而出现的一些不准确的结果, 在这些版本的mysql中, DECIMAL是一种”存储”概念类型。

在5.0以及以后的版本, mysql自己来进行DECIMAl计算, 因为cpu没有对DECIMAL的直接支持。 当然, 浮点计算在某种程度上相对快些, 因为CPU是直接支持浮点计算的。

阅读全文…

相关日志

分类: MySQL 标签: , ,

MYSQL数据库表设计与优化(二)

2010年4月19日 admin 没有评论

续 MYSQL数据库表设计与优化(一)

决定数据类型的第一步是定义所存数数据的分类: 数值型, 字符串型还是临时型等;除了一些特别的并不是那么直观的外, 这通常是很直观的。

接下来是选择具体的数据类型, 许多mysql的数据类型能存储同一种数据, 但是在可存储的数据范围, 准确度或者存储空间有些不同。 有些数据类型可能还有一些特殊的行为属性。比如, DATETIME和TIMESTAMP都能存储日期和日期, 而且都是准确到秒; 然而, TIMESTAMP占的数据空间只有DATETIME的一半, 而且是时区敏感的,同时有一些自动修改的机制。 另一个方面, 它能表示的数据范围要小些, 有些属性在某些时候是比较麻烦的。

阅读全文…

相关日志

分类: MySQL 标签: , ,

MYSQL数据库表设计与优化(一)

2010年4月17日 admin 没有评论

优化糟糕设计的表结果或者索引能很大程度改进mysql的性能。 如果需要高性能, 那么就需要根据不同的操作需求精心设计表结构和索引, 这当然需要对各种查询做出性能需求评估, 因为改变一个查询或者一部分表结构设计会在其他地方引的性能。 优化通常需要做出取舍, 例如, 通过增加索引来加速查询速度会减慢修改速度; 类似的, 一个非完全按范式设计的表结构能使某些查询速度提高, 但可能会导致其他的效率降低; 增加计数器或者汇总表能有效的优化一些查询, 但是维护代价也是不菲的。

有时候, 作为开发人员的你需要做超出开发人员职责的事情去弄清楚递到你面前的开发任务, 有时候, 那些不太了解数据库系统原理的人提出的需求可能不会考虑需求的性能影响, 如果你能清楚的告诉他们这些对数据库造成大压力的小功能需要导致硬件成本成倍增加的话, 他们可能会考虑砍掉一些需求。

阅读全文…

相关日志

分类: MySQL 标签: , ,
Easy AdSense by Unreal