山那边是海 发表于 2015-1-16 20:14:13

绝无经由的优化MySQL数据库功能的八年夜“好手”

解决方案提供商应记住DBaaS通常仅仅是解决方案的一部分。客户之所以与他们的解决方案提供商协同工作,不仅是因为他们出售的产品,而且还因为他们所提供的服务。本文切磋了进步MySQL数据库功能的思绪,并从8个方面给出了详细的办理办法。
  1、拔取最合用的字段属性
  MySQL能够很好的撑持年夜数据量的存取,可是一样平常说来,数据库中的表越小,在它下面实行的查询也就会越快。因而,在创立表的时分,为了取得更好的功能,我们能够将表中字段的宽度设得尽量小。比方,在界说邮政编码这个字段时,假如将其设置为CHAR(255),明显给数据库增添了不用要的空间,乃至利用VARCHAR这类范例也是过剩的,由于CHAR(6)就能够很好的完成义务了。一样的,假如能够的话,我们应当利用MEDIUMINT而不是BIGIN来界说整型字段。
  别的一个进步效力的办法是在大概的情形下,应当只管把字段设置为NOTNULL,如许在未来实行查询的时分,数据库不必往对照NULL值。
  关于某些文本字段,比方“省分”大概“性别”,我们能够将它们界说为ENUM范例。由于在MySQL中,ENUM范例被看成数值型数据来处置,而数值型数据被处置起来的速率要比文本范例快很多。如许,我们又能够进步数据库的功能。
  2、利用毗连(JOIN)来取代子查询(Sub-Queries)
  MySQL从4.1入手下手撑持SQL的子查询。这个手艺可使用SELECT语句来创立一个单列的查询了局,然后把这个了局作为过滤前提用在另外一个查询中。比方,我们要将客户基础信息表中没有任何定单的客户删撤除,就能够使用子查询先从发卖信息表中将一切收回定单的客户ID掏出来,然后将了局传送给主查询,以下所示:
DELETEFROMcustomerinfo
WHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)
  利用子查询能够一次性的完成良多逻辑上必要多个步骤才干完成的SQL操纵,同时也能够制止事件大概表锁逝世,而且写起来也很简单。可是,有些情形下,子查询能够被更无效率的毗连(JOIN)..替换。比方,假定我们要将一切没有定单纪录的用户掏出来,能够用上面这个查询完成:
SELECT*FROMcustomerinfo
WHERECustomerIDNOTin(SELECTCustomerIDFROMsalesinfo)
  假如利用毗连(JOIN)..来完成这个查询事情,速率将会快良多。特别是当salesinfo表中对CustomerID建有索引的话,功能将会更好,查询以下:
SELECT*FROMcustomerinfo
LEFTJOINsalesinfoONcustomerinfo.CustomerID=salesinfo.
CustomerID
WHEREsalesinfo.CustomerIDISNULL
设置数据路径,把数据库数据文件放在共享的NFS目次下(NAS服务器),
PID和innioDB文件要放到服务器当地目次上,才干一般启动、中断服务:
1125vi/etc/my.cnf

#Wheretoinstalladatabasedata
datadir=/data/mysqldata
#WheretoinstallainnoDBengine
innodb_data_home_dir=/usr/local/mysql/data
innodb_log_group_home_dir=/usr/local/mysql/data
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
1106cp./support-files/mysql.server/etc/rc.d/init.d/
vi/etc/rc.d/init.d/mysql.server
编译第222入手下手的相干的两行,把PID文件放在服务器当地目次上:
pid_file=/usr/local/mysql/data/mysqlmanager-`/bin/hostname`.pid
server_pid_file=/usr/local/mysql/data/`/bin/hostname`.pid
安装MySQL的基础数据库:
1123mount10.4.66.251:/data/data
1124mkdir/data/mysqldata
1127./scripts/mysql_install_db--user=mysql
1145chown-Rmysql.mysql/data/mysqldata/
假如一般的话,能够看到mysql一般启动了;
1146/etc/rc.d/init.d/mysql.serverstart
1146/etc/rc.d/init.d/mysql.serverstop
设置HA高可用,不要设置NFS挂载和mysql服务在启动服务器时主动运转;
5、锁定表
  只管事件是保护数据库完全性的一个十分好的办法,但却由于它的独有性,偶然会影响数据库的功能,特别是在很年夜的使用体系中。因为在事件实行的过程当中,数据库将会被锁定,因而别的的用户哀求只能临时守候直到该事件停止。假如一个数据库体系只要多数几个用户
来利用,事件酿成的影响不会成为一个太年夜的成绩;但假定有不计其数的用户同时会见一个数据库体系,比方会见一个电子商务网站,就会发生对照严峻的呼应提早。
  实在,有些情形下我们能够经由过程锁定表的办法来取得更好的功能。上面的例子就用锁定表的办法来完成后面一个例子中事件的功效。

LOCKTABLEinventoryWRITE
SELECTQuantityFROMinventory
WHEREItem=book;
...
UPDATEinventorySETQuantity=11
WHEREItem=book;
UNLOCKTABLES

  这里,我们用一个SELECT语句掏出初始数据,经由过程一些盘算,用UPDATE语句将新值更新到表中。包括有WRITE关头字的LOCKTABLE语句能够包管在UNLOCKTABLES命令被实行之前,不会有别的的会见来对inventory举行拔出、更新大概删除的操纵。
  6、利用外键
  锁定表的办法能够保护数据的完全性,可是它却不克不及包管数据的联系关系性。这个时分我们就能够利用外键。比方,外键能够包管每条发卖纪录都指向某一个存在的客户。在这里,外键能够把customerinfo表中的CustomerID映照到salesinfo表中CustomerID,任何一条没有正当CustomerID的纪录都不会被更新或拔出到salesinfo中。

CREATETABLEcustomerinfo
(
CustomerIDINTNOTNULL,
PRIMARYKEY(CustomerID)
)TYPE=INNODB;
CREATETABLEsalesinfo
(
SalesIDINTNOTNULL,
CustomerIDINTNOTNULL,
PRIMARYKEY(CustomerID,SalesID),
FOREIGNKEY(CustomerID)REFERENCEScustomerinfo
(CustomerID)ONDELETECASCADE
)TYPE=INNODB;

注重例子中的参数“ONDELETECASCADE”。该参数包管当customerinfo表中的一条客户纪录被删除的时分,salesinfo表中一切与该客户相干的纪录也会被主动删除。假如要在MySQL中利用外键,必定要记着在创立表的时分将表的范例界说为事件平安表InnoDB范例。该范例不是MySQL表的默许范例。界说的办法是在CREATETABLE语句中加上TYPE=INNODB。如例中所示。
  7、利用索引
  索引是进步数据库功能的经常使用办法,它能够令数据库服务器以比没有索引快很多的速率检索特定的行,特别是在查询语句傍边包括有MAX(),MIN()和ORDERBY这些命令的时分,功能进步更加分明。那该对哪些字段创建索引呢?一样平常说来,索引应创建在那些将用于JOIN,WHERE判别和ORDERBY排序的字段上。只管不要对数据库中某个含有大批反复的值的字段创建索引。关于一个ENUM范例的字段来讲,呈现大批反复值是很有大概的情形,比方customerinfo中的“province”..字段,在如许的字段上创建索引将不会有甚么匡助;相反,另有大概下降数据库的功能。我们在创立表的时分能够同时创立符合的索引,也能够利用ALTERTABLE或CREATEINDEX在今后创立索引。别的,MySQL
从版本3.23.23入手下手撑持全文索引和搜刮。全文索引在MySQL中是一个FULLTEXT范例索引,但仅能用于MyISAM范例的表。关于一个年夜的数据库,将数据装载到一个没有FULLTEXT索引的表中,然后再利用ALTERTABLE或CREATEINDEX创立索引,将长短常快的。但假如将数据装载到一个已有FULLTEXT索引的表中,实行历程将会十分慢。
  8、优化的查询语句
  尽年夜多半情形下,利用索引能够进步查询的速率,但假如SQL语句利用不得当的话,索引将没法发扬它应有的感化。上面是应当注重的几个方面。起首,最好是在不异范例的字段间举行对照的操纵。在MySQL3.23版之前,这乃至是一个必需的前提。比方不克不及将一个建有索引的INT字段和BIGINT字段举行对照;可是作为特别的情形,在CHAR范例的字段和VARCHAR范例字段的字段巨细不异的时分,能够将它们举行对照。其次,在建有索引的字段上只管不要利用函数举行操纵。
  比方,在一个DATE范例的字段上利用YEAE()函数时,将会使索引不克不及发扬应有的感化。以是,上面的两个查询固然前往的了局一样,但后者要比前者快很多。
SELECT*FROMorderWHEREYEAR(OrderDate)<2001;
SELECT*FROMorderWHEREOrderDate<"2001-01-01";
  一样的情况也会产生在对数值型字段举行盘算的时分:
SELECT*FROMinventoryWHEREAmount/7<24;
SELECT*FROMinventoryWHEREAmount<24*7;
  下面的两个查询也是前往不异的了局,但前面的查询将比后面的一个快良多。第三,在搜刮字符型字段时,我们偶然会利用LIKE关头字和通配符,这类做法固然复杂,但却也是以就义体系功能为价值的。比方上面的查询将会对照表中的每笔记录。
SELECT*FROMbooks
WHEREnamelike"MySQL%"
  可是假如换用上面的查询,前往的了局一样,但速率就要快上良多:..
SELECT*FROMbooks
WHEREname>="MySQL"andname<"MySQM"
  最初,应当注重制止在查询中让MySQL举行主动范例转换,由于转换历程也会使索引变得不起感化。
也许最好的策略是以不变应万变:给客户他们所需要的,不多也不少。如果MySQL学习教程适合他们,他们就不应该买别的工具。事实上,云计算产业一直推崇自助服务,但提供这些服务的公司已经开始认识到解决方案提供商推销他们商品的价值。

小魔女 发表于 2015-1-18 18:55:37

sqlserver的痛苦之处在于有用文档的匮乏,很多只是表明的东西

简单生活 发表于 2015-1-27 18:51:04

SQLServer的异构移植功能个人感觉最好了。(如果对比过SQLServer的链接服务器和Oracle的透明网关的朋友会发现SQLServer的sp_addlinkedserver(openquery)异构数据库系列比Oracle真是强太多了。)

蒙在股里 发表于 2015-2-5 14:49:08

数据库物理框架没有变动undo和redo都放在数据库得transaction中,个人感觉是个败笔。如果说我们在设计数据库的时候考虑分多个数据库,可能能在一定程度上避免I/O效率问题。

老尸 发表于 2015-2-12 09:25:01

这就引发了对varchar和char效率讨论的老问题。到底如何分配varchar的数据,是否会出现大规模的碎片?

深爱那片海 发表于 2015-3-3 02:11:54

大侠们有推荐的书籍和学习方法写下吧。

金色的骷髅 发表于 2015-3-11 09:07:41

是要和操作系统进行Socket通讯的场景。否则建议慎重!

爱飞 发表于 2015-3-18 04:46:14

如果,某一版本可以提供强大的并发响应,但是没有Oracle的相应版本稳定,或者价格较贵,那么,它就是不适合的。

再现理想 发表于 2015-3-25 13:29:49

外键的级联更能扩展可能大部分的同行在设计OLTP系统的时候都不愿意建立外键,都是通过程序来控制父子数据的完整性。
页: [1]
查看完整版本: 绝无经由的优化MySQL数据库功能的八年夜“好手”