MYSQL部分知识点
Posted sunsfan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYSQL部分知识点相关的知识,希望对你有一定的参考价值。
mysql部分知识点
- Mysql存储引擎包括MyISAM,InnoDB,BDB,MEMORY,MERGE,EXAMPLE,NDB cluster,CSV,BLACKHOLE,FEDERATED等,其中InnoDB和BDB提供事务安全表,其他存储引擎都是非事务安全表。
- MyISAM数据表,最好使用固定长度的数据列代替可变长度的数据列,MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的,对于InnoDB数据表,建议使用VARCHAR类型。
- 索引原则:搜索的索引列,不一定是所要选择的列;使用唯一索引;使用短索引;利用最左前缀;不要过度索引;考虑在列上进行的比较类型。
- SQL Injection 原理:结构化查询语言(SQL)是一种用来和数据库交互的文本语言。SQL Injection 就是利用某些数据库的外部接口把用户数据插入到实际的数据库操作语言(SQL)当中,从而达到入侵数据库乃至操作系统的目的。它的产生主要是由于程序对用户输入的数据没有进行严格
的过滤,导致非法数据库查询语句的执行。 - 检索包含最大/最小值的行:MIN() 和MAX() 的取值可以是一个字符串参数;在这些情况下, 它们返回最小或最大字符串值。DISTINCT 关键词可以被用来查找expr 的不同值的最小或最大值,然而,这产生的结果与省略DISTINCT 的结果相同。若找不到匹配的行,MIN()和MAX()返回NULL 。
- 用rand()/rand(n)提取随机行。
- 利用group by 的with rollup 子句做统计,当你使用ROLLUP时, 你不能同时使用ORDER BY子句进行结果排序。换言之, ROLLUP和ORDER BY 是互相排斥的,LIMIT 用在ROLLUP 后面。
- 用bit group functions 做统计。
- 操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。这说明在大多数Unix 中数据库名和表名对大小写敏感,而在Windows 中对大小写不敏感。尽管在某些平台中数据库名和表名对大小写不敏感,不应在同一查询中使用不同的大小写来引用给定的数据库或表。
- 列、索引、存储子程序和触发器名在任何平台上对大小写不敏感,列的别名也不敏感。默认情况,表别名在Unix 中对大小写敏感,但在Windows 或Mac OS X 中对大小写不敏感。
- 在MySQL 中,InnoDB 表支持对外部关键字约束条件的检查。对于除InnoDB 类型的表,当使用REFERENCES tbl_name(col_name)子句定义列时可以使用外部关键字,该子句没有实际的效果,只作为备忘录或注释来提醒,你目前正定义的列指向另一个表中的一个列。
- 通过show status和应用特点了解各种SQL的执行频率。
- 可以通过慢查询日志定位那些执行效率较低的sql 语句,用–log-slowqueries[=file_name]选项启动时,mysqld 写一个包含所有执行时间超过long_query_time 秒的SQL 语句的日志文件。可以链接到管理维护中的相关章节;慢查询日志在查询结束以后才纪录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题,可以使用show processlist 命令查看当前MySQL 在进行的线程,包括线程的状态,是否锁表等等,可以实时的查看SQL 执行情况,同时对一些锁表操作进行优化。
- myisam 表的数据文件和索引文件是自动分开的;innodb 的数据和索引是存储在同一个表空间里面,但可以有多个文件组成。
- 索引用于快速找出在某个列中有一特定值的行。对相关列使用索引是提高SELECT 操作性能的最佳途径。
查询要使用索引最主要的条件是查询条件中需要使用索引关键字,如果是多列索引,那么只有查询条件使用了多列关键字最左边的前缀时,才可以使用索引,否则将不能使用索引。 - 不会使用已有索引的情况:如果mysql 估计使用索引比全表扫描更慢,则不使用索引;如果使用heap 表并且where 条件中不用=索引列,其他> 、<、>=、<=均不使用索引;如果不是索引列的第一部分;如果like 是以%开始;对where 后边条件为字符串的一定要加引号,字符串如果为数字mysql 会自动转为字符串,但是不使用索引。
- 对于Myisam 类型的表,可以通过以下方式快速的导入大量的数据。
ALTER TABLE tblname DISABLE KEYS;
loading the data
ALTER TABLE tblname ENABLE KEYS;
这两个命令用来打开或者关闭Myisam 表非唯一索引的更新。在导入大量的数据到一个非空的Myisam 表时,通过设置这两个命令,可以提高导入的效率。对于导入大量数据到一个空的Myisam 表,默认就是先导入数据然后才创建索引的,所以不用进行设置。 - 因为Innodb 类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数据的效率。如果Innodb 表没有主键,那么系统会默认创建一个内部列作为主键,所以如果可以给表创建一个主键,将可以利用这个优势提高导入数据的效率;在导入数据前执行SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率;如果应用使用自动提交的方式,建议导入前执行SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。
- 如果你同时从同一客户插入很多行,使用多个值表的INSERT 语句。这比使用分开INSERT 语句快(在一些情况中几倍)。
- 如果你从不同客户插入很多行,能通过使用INSERT DELAYED 语句得到更高的速度。Delayed 的含义是让insert 语句马上执行,其实数据都被放在内存的队列中,并没有真正写入磁盘;这比每条语句分别插入要快的多;LOW_PRIORITY 刚好相反,在所有其他用户对表的读写完后才进行插入。
- 将索引文件和数据文件分在不同的磁盘上存放(利用建表中的选项);如果进行批量插入,可以增加bulk_insert_buffer_size 变量值的方法来提高速度,但是,这只能对myisam 表使用;当从一个文本文件装载一个表时,使用LOAD DATA INFILE。这通常比使用很多INSERT 语句快20 倍;根据应用情况使用replace 语句代替insert;根据应用情况使用ignore 关键字忽略重复记录。
- 对于or 子句,如果要利用索引,则or 之间的每个条件列都必须用到索引;如果没有索引,则应该考虑增加索引。
- MySQL 的默认的调度策略可用总结如下:写入操作优先于读取操作;对某张数据表的写入操作某一时刻只能发生一次,写入请求按照它们到达的次序来处理;对某张数据表的多个读取操作可以同时地进行。
- 其他优化措施:使用持久的连接数据库以避免连接开销;经常检查所有查询确实使用了必要的索引;避免在频繁更新的表上执行复杂的SELECT 查询,以避免与锁定表有关的由于读、写冲突发生的问题;对于没有删除的行操作的MyISAM 表,插入操作和查询操作可以并行进行,因为没有删除操作的表查询期间不会阻塞插入操作.对于确实需要执行删除操作的表,尽量在空闲时间进行批量删除操作,避免阻塞其他操作;充分利用列有默认值的事实。只有当插入的值不同于默认值时,才明确地插入值。这减少MySQL 需要做的语法分析从而提高插入速度;对经常访问的可以重构的数据使用内存表,可以显著提高访问的效率;通过复制可以提高某些操作的性能。可以在复制服务器中分布客户的检索以均分负载。
为了防止备份期间对应用的影响,可以在复制服务器上执行备份操作;表的字段尽量不使用自增长变量,在高并发情况下该字段的自增可能对效率有比较大的影响,推荐通过应用来实现字段的自增长。 - 通过拆分,提高表的访问效率,主要针对MyISAM存储引擎:纵向拆分是只按照应用访问的频度,将表中经常访问的字段和不经常访问的字段拆分成两个表,经常访问的字段尽量是定长的,这样可以有效的提高表的查询和更新的效率;横向拆分是指按照应用的情况,有目的的将数据横向拆分成几个表或者通过分区分到多个分区中,这样可以有效的避免Myisam 表的读取和更新导致的锁问题。
- 表级锁在下列几种情况下比行级锁更优越:很多操作都是读表;在严格条件的索引上读取和更新,当更新或者删除可以用单独的索引来读取得到时;UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;DELETE FROM tbl_name WHERE unique_key_col=key_value;SELECT 和INSERT 语句并发的执行,但是只有很少的UPDATE 和DELETE 语句;很多的扫描表和对全表的GROUP BY 操作,但是没有任何写表。
- 行级锁定的优点:当在许多线程中访问不同的行时只存在少量锁定冲突;回滚时只有少量的更改;可以长时间锁定单一的行。行级锁定的缺点:比页级或表级锁定占用更多的内存;当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁;如果你在大部分数据上经常进行GROUP BY 操作或者必须经常扫描整个表,比其它锁定
明显慢很多;用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。 - 如何减少锁冲突。对Myisam 类型的表:Myisam 类型的表可以考虑通过改成Innodb 类型的表来减少锁冲突;根据应用的情况,尝试横向拆分成多个表或者改成Myisam 分区对减少锁冲突也会有一定的帮助。对Innodb 类型的表:首先要确认,在对表获取行锁的时候,要尽量的使用索引检索纪录,如果没有使用索引访问,那么即便你只是要更新其中的一行纪录,也是全表锁定的。要确保sql是使用索引来访问纪录的,必要的时候,请使用explain 检查sql 的执行计划,判断是否按照预期使用了索引;由于mysql 的行锁是针对索引加的锁,不是针对纪录加的锁,所以虽然是访问不同行的纪录,但是如果是相同的索引键,是会被加锁的。应用设计的时候也要注意,这里和Oracle 有比较大的不同;当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,当表有主键或者唯一索引的时候,不是必须使用主键或者唯一索引锁定纪录,其他普通索引同样可以用来检索纪录,并只锁定符合条件的行;用SHOW INNODB STATUS 来确定最后一个死锁的原因。查询的结果中,包括死锁的事务的详细信息,包括执行的SQL 语句的内容,每个线程已经获得了什么锁,在等待什么锁,以及最后是哪个线程被回滚。详细的分析死锁产生的原因,可以通过改进程序有效的避免死锁的产生;如果应用并不介意死锁的出现,那么可以在应用中对发现的死锁进行处理;确定更合理的事务大小,小事务更少地倾向于冲突;如果你正使用锁定读,(SELECT … FOR UPDATE 或… LOCK IN SHARE MODE),试着用更低的隔离级别,比如READ COMMITTED;以固定的顺序访问你的表和行,则事务形成良好定义的查询并且没有死锁。
- 应用中需要理清楚对数据库的访问逻辑,需要对相同表的访问,尽量集中在相同sql访问,一次提取结果,减少对数据库的重复访问。
- 利用mysql 的主从复制可以有效的分流更新操作和查询操作,具体的实现是一个主服务器,承担更新操作,多台从服务器,承担查询操作,主从之间通过复制实现数据的同步。多台从服务器一方面用来确保可用性,一方面可以创建不同的索引满足不同查询的需要。
以上是关于MYSQL部分知识点的主要内容,如果未能解决你的问题,请参考以下文章