目前要求就是统计任意一个SQL的结果集总数。要求效率最好的。
我现在是用mysql_num_rows,除了使用方便外,执行效率真不好。
还有就是count,有条件的时候count(*)好像也不太好使了。
不知能用什么方法了。
sql不固定、是任意的。***************************** `ip` 存储引擎 InnoDB *****************************SQL:
SELECT * FROM `ip` where ipid > 1400
用PHP的mysql_num_rows()统计。
用时:
1138446 / 4.77450秒
SQL:
SELECT count(*) FROM `ip` where ipid > 1400
用时:
Array ( [count(*)] => 1138446 ) 2.300020秒
SQL:
SELECT count(*) FROM `ip`
用时:
Array ( [count(*)] => 1139704 ) 2.390520秒***************************** `ip1` 存储引擎 MyISAM *****************************
SQL:
SELECT * FROM `ip1` where ipid > 1400
用PHP的mysql_num_rows()统计。
用时:
1138446 / 2.026050秒
SQL:
SELECT count(*) FROM `ip1` where ipid > 1400
用时:
Array ( [count(*)] => 1138446 ) 0.564690秒
SQL:
SELECT count(*) FROM `ip1`
用时:
Array ( [count(*)] => 1139704 ) 0.000220秒
具体什么问题
SELECT * FROM ... WHERE ...
用
SELECT FOUND_ROWS()即可得到行数
这个并没有好办法,如果是任意的查询,则无法利用索引,只能通过全表扫描来得到结果集进行统计。
但总体上 select count(*) 要优于 mysql_num_rows, 因为这个至少不需要返回这么大的结果集。直接由MYSQL进行统计。
SQL_CALC_FOUND_ROWS 问题一。问题二。加上贼慢了。
查询
SELECT SQL_CALC_FOUND_ROWS * FROM `item_sell_20110823` WHERE num_iid > 1000 LIMIT 10
查询花费 2.74143秒。不加SQL_CALC_FOUND_ROWS 0.00048秒。 SELECT FOUND_ROWS()
Array ( [FOUND_ROWS()] => 897546 )
行不通。
用时:
Array ( [count(*)] => 1139704 ) 2.390520秒像这个的话。还需2秒。2秒极限了? 没别的方法了啊。。
sql是无限制查询啊。。所以任意的。需要得获sql查询得到结果的总记录数。数据量大的时候就不好了。这问题得解决........
如果不考虑其它因素、每limit几十条数据就得花费2、3秒。实在让人受不了。还有像下面那个MyISAM表。
SQL:
SELECT count(*) FROM `ip1` where ipid > 1400
用时:
Array ( [count(*)] => 1138446 ) 0.564690秒
SQL:
SELECT count(*) FROM `ip1`
用时:
Array ( [count(*)] => 1139704 ) 0.000220秒
这是为何呐? 相差这么大。
MYISAM表当直接SELECT COUNT(*)不做任何WHERE时,MYSQL直接从数据字典取该表的记录总数。
速度如何
Array ( [count(ipid)] => 1138446 ) 2.407130SELECT count(ipid) FROM `ip1` where ipid > 1400 // MyISAM
Array ( [count(ipid)] => 1138446 ) 0.571370
一样啊。测试结果还比1楼的慢点点.....
测试了一下,在大约10万条的表,引擎INNODB,执行
SELECT SQL_NO_CACHE COUNT(*) FROM TMP WHERE F1>='123'
只要0.007秒,在F1上有索引
sELECT SQL_CALC_FOUND_ROWS * FROM `item_sell_20110823` WHERE num_iid > 1000 LIMIT 10->select a.* from `item_sell_20110823` a inner join
(select num_iid from `item_sell_20110823` WHERE num_iid > 1000 LIMIT 10 ) b
on a.num_iid=b.num_iid
+----------+
| count(*) |
+----------+
| 1139704 |
+----------+
1 row in set (2.22 sec)
MyISAM ****************************************************
mysql> SELECT SQL_NO_CACHE count(*) FROM `ip1` where ipid > 1400
-> ;
+----------+
| count(*) |
+----------+
| 1138446 |
+----------+
1 row in set (0.56 sec)mysql> SELECT count(*) FROM `ip2`;
+----------+
| count(*) |
+----------+
| 379901 |
+----------+
1 row in set (0.00 sec)mysql> SELECT count(*) FROM `ip2` WHERE ipid > 1400;
+----------+
| count(*) |
+----------+
| 378643 |
+----------+
1 row in set (0.24 sec)mysql>
测了一个30多万的还是MyISAM。 0.24 sec
这个昨晚有测了。要2秒多。不加SQL_CALC_FOUND_ROWS 0.00048秒。select a.* from `item_sell_20110823` a inner join
(select num_iid from `item_sell_20110823` WHERE num_iid > 1000 LIMIT 10 ) b
on a.num_iid=b.num_iid
这个你干啥子哦。这表不在公司。测不了。
不知怎么做的。
(select num_iid from `item_sell_20110823` WHERE num_iid > 1000 LIMIT 10 ) b
on a.num_iid=b.num_iid
这个你干啥子哦。这表不在公司。测不了。
替换
sELECT SQL_CALC_FOUND_ROWS * FROM `item_sell_20110823` WHERE num_iid > 1000 LIMIT 10
这个语句
原来他是读TABLES.TABLE_ROWS这个字段的。
InnoDB的统计不准确。InnoDB表有WHERE的SQL,phpmyadmin也是查询得很慢。
时间主要是花费在统计总数上了。
难怪 教科书上例子都是 *
动不动就 *
如果先这么弄的话:ALTER TABLE TBNAME ENGINE=MYISAM 就只这个花费时间就多于count(*)时间了。