php数据库加速 php添加数据库( 二 )


还可以使用并集来避免顺序存取 。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取 。下面的查询将强迫对orders表执行顺序操作:
SELECT * FROM orders WHERE (customer_num=104 AND order_num1001) OR order_num=1008
虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表 。因为这个语句要检索的是分离的行的 *** ,所以应该改为如下语句:
SELECT * FROM orders WHERE customer_num=104 AND order_num1001
UNION
SELECT * FROM orders WHERE order_num=1008
这样就能利用索引路径处理查询 。
4.避免相关子查询
一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后 , 子查询必须重新查询一次 。查询嵌套层次越多 , 效率越低,因此应当尽量避免子查询 。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行 。
5.避免困难的正规表达式
MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式 。但这种匹配特别耗费时间 。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”
即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式 。如果把语句改为SELECT * FROM customer WHERE zipcode “98000” , 在执行查询时就会利用索引来查询 , 显然会大大提高速度 。
另外,还要避免非开始的子串 。例如语句:SELECT * FROM customer WHERE zipcode[2,3]“80”,在where子句中采用了非开始子串 , 因而这个语句也不会使用索引 。
6.使用临时表加速查询
把表的一个子集进行排序并创建临时表,有时能加速查询 。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作 。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance0
AND cust.postcode“98000”
ORDER BY cust.name
如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
【php数据库加速 php添加数据库】AND rcvblls.balance0
ORDER BY cust.name
INTO TEMP cust_with_balance
然后以下面的方式在临时表中查询:
SELECT * FROM cust_with_balance
WHERE postcode“98000”
临时表中的行要比主表中的行少 , 而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少 。
注意:临时表创建后不会反映主表的修改 。在主表中数据频繁修改的情况下 , 注意不要丢失数据 。
7.用排序来取代非顺序存取
非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动 。SQL语句隐藏了这一情况 , 使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询 。
有些时候,用数据库的排序能力来替代非顺序的存取能改进查询 。
实例分析
下面我们举一个制造公司的例子来说明如何进行查询优化 。制造公司数据库中包括3个表,模式如下所示:
1.part表
零件号?????零件描述????????其他列
(part_num)?(part_desc)??????(other column)
102,032???Seageat 30G disk?????……
500,049???Novel 10M neork card??……
……
2.vendor表
厂商号??????厂商名??????其他列

推荐阅读