Database

MySQL表字段类型选择:长度越小越好,类型越简单越好

字段长度越小越好 字段长度越大,占用的内存、磁盘空间越大,读写时的I/O代价就越高, 同时占用的cpu周期越多。 所以,能用int, 就别用bigint.  不过,benchmarking表明,这个差别其实也不是很大。 表中数据量 操作 并发数 int类型的QPS bigint类型QPS N/A 逐渐插入100条数据到空表中 100 1092 1071 1百万 查询 100 5615 5451 注1:阿里云服务器,CPU 2核, 内存4GB, 64位CentOS, MySQL版本5.1.73,InnoDB 注2:每轮执行完后都会重启MySQL, 以消除缓存的影响 字段类型越简单越好 字段类型越复杂,占用的cpu周期越多;复杂类型的字段处理起来可能还有额外的逻辑,导致更加耗时。比如varchar类型的大小比较会牵涉到charset和collation,逻辑相对复杂,性能不如int类型。 所以, 1. 能用int, 就别用varchar 2. 如果对精度要求不高,能用float/double, 就不要用decimal 这里有人对“把IP存成varchar还是unsigned int”做了下benchmarking. 他说, 引用 Storing IPs as a string, besides requiring more disk space, takes 9% longer than …

MySQL表字段类型选择:长度越小越好,类型越简单越好 Read More »

一次使用Super Smack进行MySQL benchmarking的完整经历 – 下篇:运行测试

测试要解决的问题 索引字段上是否存在空数据,对查询性能的影响有多大? 基本步骤概括 测试的准备可以分为两大部分:准备测试数据和配置smack文件。 Super Smack和其他的一些benchmark工具一样,可以把“测试数据准备”也做了,包括按需建表、导入数据等等。我原本也想让Super Smack把这一步包了,但经过反复尝试后还是放弃了: 1. Super Smack的建表和导数据的触发条件比较复杂,又老是出各种各样的错,很难解决。与其让它代劳,还不如自己执行load data更可控。 2. 在测试执行过程中临时删表(drop)、建表、导数据,这种方案本身并不可取。日常开发中,我们的表本来就建好了,不需要依赖测试工具来临时创建,而且我们也不能容许测试工具在测试过程中或测试完成后自动删除表格. 所以, 我建议使用的基本方案是: 1. 自己手动完成测试数据的准备。 2. Super Smack只管执行测试语句。 测试数据准备 –建两张表,一张允许索引字段为空,另一张不允许为空 drop table if exists index_nullable; drop table if exists index_not_nullable; create table index_nullable ( id bigint unsigned not null auto_increment, name varchar(50) default null, key idx_name (name), primary key(id) ); create table index_not_nullable …

一次使用Super Smack进行MySQL benchmarking的完整经历 – 下篇:运行测试 Read More »

MySQL: varchar v.s. char

从SQL性能来说,两者是差不多的。有人做过benchmarking. http://blog.csdn.net/yunhua_lee/article/details/7038780 性能方面有一点可以注意:由于char类型字段可以一次性分配到固定长度的空间,系统一般会给它分配一段连续的空间,这样的话数据一般不会被fragmentation, 对性能有一定好处。 至于存储空间,一般都会用varchar以避免浪费空间,定长的类型则可以用char.

MySQL: 查看一次SQL的执行时间都花在哪些环节上

select @@profiling — 看看当前的session的profiling打开没有 set profiling = 1 — 如果没打开,打开一下 — 执行一些sql select count(*) … select * from … show profiles — 查看所有已执行的profile show profile for query 2 — 看看刚才某条sql执行的具体时间拆分,2是个某个query id show profile cpu for query 2 — 看看刚才某条sql执行的具体时间拆分,并加上相应的cpu信息 (cpu也可以换成all,以查看更多系统指标)

innodb的record lock, row lock, gap lock, next-key lock

record lock – 对索引上某个记录的锁 row lock -对某条数据记录的锁。然而innodb总是通过施加record lock来施加row lock, 也就是说innodb本身没有row lock的概念,record lock就是row lock gap lock – 索引record之间的锁,用来防止phantom read next-key lock – 本身不是一种锁。它是a combination of a record lock on the index record and a gap lock on the gap before the index record.  用next-key lock可以防止phantom read. 对于这样一条语句, SELECT * FROM child WHERE id > 100 FOR …

innodb的record lock, row lock, gap lock, next-key lock Read More »

mysql: 了解数据库状态时常用的sql语句

show table status like ‘some_table’ 它会给出本表的storage engine, 行数,表占的空间和索引所占的空间。还有一个有意思的信息:每行平均所占的空间。这个信息不仅可用于DB管理,也可以帮助在整个信息系统中估计各种存储空间、网络带宽之类的。 show variables like ‘%slow%’ show variables  like ‘%long%’;   了解慢查询相关的设置 show variables like ‘storage_engine’; 查看当前默认的storage engine show full processlist 当前连到本库的客户端进程 show variables like ‘query_cache_type’ 查看数据库的query cache设置

two-phase locking

two-phase locking(2pl)是指在一个事务分成两个阶段: 1. 第1阶段只能加锁 2. 第2阶段只能释放锁 它的反面就是: 对A加锁,然后释放; 再加B锁,再释放。。。 后面这种方式保证不了serializability.   比如, 事务甲               事务乙 ———————- 对A加写锁 set A=100 对A释放写锁                       对A加写锁                       set A=200                       对A释放写锁 对A加读锁 对B加写锁 set B=A*2=… select B 对A释放读锁     对B释放写锁               ———————- 事务甲结束后,B的值变成了400; 而我们本来预期这个值应该是200的 (没有满足repeatable read这个级别) 要解决这个问题,可以干脆等事务甲全部结束再执行事务乙;既然事务之间是通过锁来协调的,可以让事务甲的锁全部释放了,再让事务乙获得锁,以保证一致性。 事务甲               事务乙 ———————- 对A加写锁 set A=100                       对A加写锁                       等待。。。。 对B加写锁 set B=A*2=…                  select B …

two-phase locking Read More »

innodb中,每条语句都运行在事务中

autocommit下,每条语句组成一个事务: "In InnoDB, all user activity occurs inside a transaction. If autocommit mode is enabled, each SQL statement forms a single transaction on its own" "By default, MySQL starts the session for each new connection with autocommit enabled, so MySQL does a commit after each SQL statement if that statement did not return an error." …

innodb中,每条语句都运行在事务中 Read More »