if (!lstat(to,&stat_buff)) /* Check if it's a symbolic link */ if (S_ISLNK(stat_buff.st_mode) && realpath(to,buff))
把代码改变为这样:
if (realpath(to,buff))
10.2.3 调节服务器参数 你能用这个命令得到mysqld服务器缺省缓冲区大小:
shell> mysqld --help
这个命令生成一张所有mysqld选项和可配置变量的表。输出包括缺省值并且看上去象这样一些东西:
Possible variables for option --set-variable (-O) are: back_log current value: 5 connect_timeout current value: 5 delayed_insert_timeout current value: 300 delayed_insert_limit current value: 100 delayed_queue_size current value: 1000 flush_time current value: 0 interactive_timeout current value: 28800 join_buffer_size current value: 131072 key_buffer_size current value: 1048540 lower_case_table_names current value: 0 long_query_time current value: 10 max_allowed_packet current value: 1048576 max_connections current value: 100 max_connect_errors current value: 10 max_delayed_threads current value: 20 max_heap_table_size current value: 16777216 max_join_size current value: 4294967295 max_sort_length current value: 1024 max_tmp_tables current value: 32 max_write_lock_count current value: 4294967295 net_buffer_length current value: 16384 query_buffer_size current value: 0 record_buffer current value: 131072 sort_buffer current value: 2097116 table_cache current value: 64 thread_concurrency current value: 10 tmp_table_size current value: 1048576 thread_stack current value: 131072 wait_timeout current value: 28800
mysql> SELECT * FROM tbl_name WHERE col1=val1; mysql> SELECT * FROM tbl_name WHERE col2=val2; mysql> SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
... WHERE index_part1=1 AND index_part2=2 ... WHERE index=1 OR A=10 AND index=2 /* index = 1 OR index = 2 */ ... WHERE index_part1='hello' AND index_part_3=5 /* optimized like "index_part1='hello'" */
这些WHERE子句不使用索引:
... WHERE index_part2=1 AND index_part3=2 /* index_part_1 is not used */ ... WHERE index=1 OR A=10 /* No index */ ... WHERE index_part1=1 OR index_part2=10 /* No index spans all rows */
注意,上述不意味着你的应用程序将缓慢地以 N log N 退化!当表格变得更大时,只要一切被OS或SQL服务器缓冲,事情将仅仅或多或少地更慢。在数据变得太大不能被缓冲后,事情将开始变得更慢直到你的应用程序仅仅受磁盘寻道限制(它以N log N增加)。为了避免这个增加,索引缓冲随数据增加而增加。见10.2.3 调节服务器参数。
10.5.2 SELECT查询的速度 总的来说,当你想要使一个较慢的SELECT ... WHERE更快,检查的第一件事情是你是否能增加一个索引。见10.4 MySQL 索引的使用。在不同表之间的所有引用通常应该用索引完成。你可以使用EXPLAIN来确定哪个索引用于一条SELECT语句。见7.22 EXPLAIN句法(得到关于一条SELECT的信息)。
mysql> SELECT COUNT(*) FROM tbl_name; mysql> SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name; mysql> SELECT MAX(key_part2) FROM tbl_name WHERE key_part_1=constant; mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10; mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
下列查询仅使用索引树就可解决(假设索引列是数字的):
mysql> SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val; mysql> SELECT COUNT(*) FROM tbl_name WHERE key_part1=val1 AND key_part2=val2; mysql> SELECT key_part2 FROM tbl_name GROUP BY key_part1;
下列查询使用索引以排序顺序检索,不用一次另外的排序:
mysql> SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... mysql> SELECT ... FROM tbl_name ORDER BY key_part1 DESC,key_part2 DESC,...
10.5.4 MySQL怎样优化LEFT JOIN 在MySQL中,A LEFT JOIN B实现如下:
连接:(3) 发送查询给服务器:(2) 分析查询:(2) 插入记录:(1 x 记录大小) 插入索引:(1 x 索引) 关闭:(1) 这里的数字有点与总体时间成正比。这不考虑打开表的初始开销(它为每个并发运行的查询做一次)。
表的大小以N log N (B 树)的速度减慢索引的插入。
加快插入的一些方法:
如果你同时从同一客户插入很多行,使用多个值表的INSERT语句。这比使用分开INSERT语句快(在一些情况中几倍)。 如果你从不同客户插入很多行,你能通过使用INSERT DELAYED语句得到更高的速度。见7.14 INSERT句法。 注意,用MyISAM,如果在表中没有删除的行,能在SELECT:s正在运行的同时插入行。 当从一个文本文件装载一个表时,使用LOAD DATA INFILE。这通常比使用很多INSERT语句快20倍。见7.16 LOAD DATA INFILE句法。 当表有很多索引时,有可能多做些工作使得LOAD DATA INFILE更快些。使用下列过程: 有选择地用CREATE TABLE创建表。例如使用mysql或Perl-DBI。 执行FLUSH TABLES,或外壳命令mysqladmin flush-tables。 使用myisamchk --keys-used=0 -rq /path/to/db/tbl_name。这将从表中删除所有索引的使用。 用LOAD DATA INFILE把数据插入到表中,这将不更新任何索引,因此很快。 如果你有myisampack并且想要压缩表,在它上面运行myisampack。见10.6.3 压缩表的特征。 用myisamchk -r -q /path/to/db/tbl_name再创建索引。这将在将它写入磁盘前在内存中创建索引树,并且它更快,因为避免大量磁盘寻道。结果索引树也被完美地平衡。 执行FLUSH TABLES,或外壳命令mysqladmin flush-tables。 这个过程将被构造进在MySQL的某个未来版本的LOAD DATA INFILE。
你可以锁定你的表以加速插入。 mysql> LOCK TABLES a WRITE; mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33); mysql> INSERT INTO a VALUES (8,26),(6,29); mysql> UNLOCK TABLES;
CREATE TEMPORARY TABLE test TYPE=HEAP SELECT tab2.a as a2, tab3.a as a3 FROM tab2, tab3 WHERE tab2.a = tab3.a and c = 0; SELECT tab1.a, test.a3 from tab1, test where tab1.a = test.a1; SELECT tab1.b, test.a3 from tab1, test where tab1.a = test.a1 and something;
我们最初的感觉是Linux在低到中等负载时执行的较好,但是你开始得到导致的高负载时,Solaris将表现更好,因为磁盘IO的极限,但是我们还没有关于这方面的任何结论。在与一些Linux核心开发者的讨论以后,这可能是 Linux 的副作用,它给批处理以太多的资源使得交互的性能变得很低。当大的批处理正在进行时,这使机器感觉很慢且无反应。希望这将在未来的Linux内核中解决。