|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
我先把我自己学习PHP的过程做一下概括: <P style="TEXT-INDENT: 2em">当你提交一个查询的时分,MySQL会剖析它,看是不是可以做一些优化使处置该查询的速度更快。这一局部将引见查询优化器是若何任务的。假如你想晓得MySQL采取的优化手腕,可以检查MySQL参考手册。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">固然,MySQL查询优化器也使用了索引,然而它也利用了其它一些信息。例如,假如你提交以下所示的查询,那末不管数据表有多大,MySQL履行它的速度城市十分快: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">SELECT * FROM tbl_name WHERE 0; <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">在这个例子中,MySQL检查WHERE子句,熟悉到没有合适查询前提的数据行,因而基本就不思索搜刮数据表。你可以经由过程供应一个EXPLAIN语句看到这类情形,这个语句让MySQL显示本人履行的但实践上没有真正地履行的SELECT查询的一些信息。假如要利用EXPLAIN,只需求在EXPLAIN单词放在SELECT语句的后面: <P style="TEXT-INDENT: 2em">- mysql> EXPLAIN SELECT * FROM tbl_name WHERE 0\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: NULL type: NULL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL Extra: Impossible WHERE
复制代码 <P style="TEXT-INDENT: 2em">凡是情形下,EXPLAIN前往的信息比下面的信息要多一些,还包含用于扫描数据表的索引、利用的联合类型、每张数据表中估量需求反省的数据行数目等非空(NULL)信息。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">优化器是若何任务的 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">MySQL查询优化器有几个方针,然而个中最次要的方针是尽量地利用索引,而且利用最严厉的索引来消弭尽量多的数据行。你的终究方针是提交SELECT语句查找数据行,而不是扫除数据行。优化器试图扫除数据行的缘由在于它扫除数据行的速度越快,那末找到与前提婚配的数据行也就越快。假如可以起首停止最严厉的测试,查询就能够履行地更快。假定你的查询查验了两个数据列,每一个列上都有索引: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">- SELECT col3 FROM mytable WHERE col1 = ’some value’ AND col2 = ’some other value’;
复制代码 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">假定col1上的测试婚配了900个数据行,col2上的测试婚配了300个数据行,而同时停止的测试只失掉了30个数据行。先测试Col1会有900个数据行,需求反省它们找到个中的30个与col2中的值婚配纪录,个中就有870次是掉败了。先测试col2会有300个数据行,需求反省它们找到个中的30个与col1中的值婚配的纪录,只要270次是掉败的,因而需求的盘算和磁盘I/O更少。其了局是,优化器会先测试col2,由于如许做开支更小。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">你可以经由过程上面一个指点匡助优化器更好天时用索引: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">尽可能对照数据类型不异的数据列。当你在对照操作中利用索引数据列的时分,请利用数据类型不异的列。不异的数据类型比分歧类型的功能要高一些。例如,INT与BIGINT是分歧的。CHAR(10)被以为是CHAR(10)或VARCHAR(10),然而与CHAR(12)或VARCHAR(12)分歧。假如你所对照的数据列的类型分歧,那末可使用ALTER TABLE来修正个中一个,使它们的类型相婚配。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">尽量地让索引列在对照表达式中自力。假如你在函数挪用或更庞杂的算术表达式前提中利用了某个数据列,MySQL就不会利用索引,由于它必需盘算出每一个数据行的表达式值。有时分这类情形没法防止,然而良多情形下你可以从头编写一个查询让索引列自力地呈现。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">上面的WHERE子句显示了这类情形。它们的功效不异,然而关于优化方针来讲就有很大差别了: <P style="TEXT-INDENT: 2em">- WHERE mycol < 4 / 2 WHERE mycol * 2 < 4
复制代码 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">关于第一行,优化器把表达式4/2简化为2,接着利用mycol上的索引来疾速地查找小于2的值。关于第二个表达式,MySQL必需检索出每一个数据行的mycol值,乘以2,接着把了局与4停止对照。在这类情形下,不会利用索引。数据列中的每一个值都必需被检索到,如许才干盘算出对照表达式右边的值。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">咱们看别的一个例子。假定你对date_col列停止了索引。假如你提交一条以下所示的查询,就不会利用这个索引: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">SELECT * FROM mytbl WHERE YEAR(date_col) < 1990; <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这个表达式不会把1990与索引列停止对照;它会把1990与该数据列盘算出来的值对照,而每一个数据行都必需盘算出这个值。其了局是,没有利用date_col上的索引,由于履行如许的查询需求全表扫描。怎样处理这个成绩呢?只需求利用文今天期,接着就能够利用date_col上的索引来查找列中婚配的值了: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">WHERE date_col < ’1990-01-01’ <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">然而,假定你没有特定的日期。你能够但愿找到一些与明天相隔固定的几天的日期的纪录。表达这类类型的对照有良多种办法--它们的效力其实不同。上面就有三种: <P style="TEXT-INDENT: 2em">- WHERE TO_DAYS(date_col) - TO_DAYS(CURDATE()) < cutoff WHERE TO_DAYS(date_col) < cutoff + TO_DAYS(CURDATE()) WHERE date_col < DATE_ADD(CURDATE(), INTERVAL cutoff DAY)
复制代码 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">关于第一行,不会用到索引,由于每一个数据行都必需检索以盘算出TO_DAYS(date_col)的值。第二行要好一些。Cutoff和TO_DAYS(CURDATE())都是常量,因而在处置查询之前,对照表达式的右侧可以被优化器一次性盘算出来,而不需求每一个数据行都盘算一次。然而date_col列依然呈现在函数挪用中,它禁止了索引的利用。第三行是这几个中最好的。一样,在履行查询之前,对照表达式的右侧可以作为常量一次性盘算出来,然而如今它的值是一个日期。这个值可以直接与date_col值停止对照,不再需求转换成天数了。在这类情形下,会利用索引。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">在LIKE形式的开首不要利用通配符。有些字符串搜刮利用以下所示的WHERE子句: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">WHERE col_name LIKE ’%string%’ <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">假如你但愿找到那些呈现在数据列的任何地位的字符串,这个语句就是对的。然而不要由于习气而复杂地把"%"放在字符串的双方。假如你在查找呈现在数据列开首的字符串,就删失落后面的"%"。假定你要查找那些相似MacGregor或MacDougall等以"Mac"开首的名字。在这类情形下,WHERE子句以下所示: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">WHERE last_name LIKE ’Mac%’ <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">优化器检查该形式中词首的文本,并利用索引找到那些与上面的表达式婚配的数据行。上面的表达式是利用last_name索引的另外一种模式: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">WHERE last_name >= ’Mac’ AND last_name < ’Mad’ <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">这类优化不克不及使用于利用了REGEXP操作符的形式婚配。REGEXP表达式永久不会被优化。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">匡助优化器更好的判别索引的效力。在默许情形下,当你把索引列的值与常量停止对照的时分,优化器会假定键值在索引外部是平均散布的。在决意停止常量对照是不是利用索引的时分,优化器会疾速地反省索引,估量出会用到几何个实体(entry)。对应MyISAM、InnoDB和BDB数据表来讲,你可使用ANALYZE TABLE让办事器履行对键值的剖析。它会为优化器供应更好的信息。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">利用EXPLAIN验证优化器的操作。EXPLAIN语句可以告知你是不是利用了索引。当你试图用别的的体例编写语句或反省添加索引是不是会进步查询履行效力的时分,这些信息对你是有匡助的。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">在需要的时分给优化器一些提醒。正常情形下,MySQL优化器自在地决意扫描数据表的次第来最快地检索数据行。在有些场所中优化器没有作出最好选择。假如你发觉这类景象产生了,就能够利用STRAIGHT_JOIN关头字来重载优化器的选择。带有STRAIGHT_JOIN的联合相似于穿插联合,然而强制数据表依照FROM子句中指定的次第来联合。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">在SELECT语句中有两个中央可以指定STRAIGHT_JOIN。你可以在SELECT关头字和选择列表之间的地位指定,如许会对语句中一切的穿插联合发生影响;你也能够在FROM子句中指定。上面的两个语句功效不异: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">- SELECT STRAIGHT_JOIN ... FROM t1, t2, t3 ... ; SELECT ... FROM t1 STRAIGHT_JOIN t2 STRAIGHT_JOIN t3 ... ;
复制代码 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">分离在带有STRAIGHT_JOIN和不带STRAIGHT_JOIN的情形下运转这个查询;MySQL能够由于甚么缘由没有依照你以为最好的次第利用索引(你可使用EXPLAIN来反省MySQL处置每一个语句的履行企图)。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">你还可使用FORCE INDEX、USE INDEX或IGNORE INDEX来指点办事器若何利用索引。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">使用优化器加倍完美的区域。MySQL可以履行联合和子查询,然而子查询是比来才撑持的,是在MySQL 4.1中添加的。因此在良多情形下,优化器春联结操作的调剂比对子查询的调剂要好一些。当你的子查询履行地很慢的时分,这就是一条实践的提醒。有一些子查询可使用逻辑上相等的联合来从头表达。在可行的情形下,你可以把子查询从头改写为联合,看是不是履行地快一些。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">测试查询的备用模式,屡次运转。当你测试查询的备用模式的时分(例如,子查询与同等的联合操尴尬刁难比),每种体例都应当屡次运转。假如两种模式都只运转了一次,那末你凡是会发明第二个查询比第一个快,这是由于第一个查询失掉的信息依然保存在缓存中,以致于第二个查询没有真正地从磁盘上读取数据。你还应当在体系负载绝对安稳的时分运转查询,以免体系中其它的事务影响了局。 <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">防止过度地利用MySQL主动类型转换。MySQL会履行主动的类型转换,然而假如你可以防止这类转换操作,你失掉的功能就更好了。例如,假如num_col是整型数据列,那末上面这些查询将前往不异的了局: <P style="TEXT-INDENT: 2em"><P style="TEXT-INDENT: 2em">- SELECT * FROM mytbl WHERE num_col = 4; SELECT * FROM mytbl WHERE num_col = ’4’;
复制代码 <P style="TEXT-INDENT: 2em">然而第二个查询触及到了类型转换。转换操作自己为了把整型和字符串型转换为双精度型停止对照,使功能好转了。更严重的情形是,假如num_col是索引的,那末触及到类型转换的对照操作不会利用索引。
终于理解了数据库的概念,而且让你兴奋不已的是你终于可以通过PHP来连接数据库了,这期间你是怎么学会的,我们不去考证了,但是事实证明,你已经可以了。 |
|