使用mysql计算大表的最快方法是什么


what is the fastest way to count a large table using mysql

我发现很难决定从where语句过滤的表中计算某些特定记录的最快方法这是我的代码,这是查询:

$type_mo3ln_malk = mysql_num_rows(mysql_query("SELECT * FROM `tableshow` $weress AND mo3ln_type='malk'"));
$type_mo3ln_mswg = mysql_num_rows(mysql_query("SELECT * FROM `tableshow` $weress AND mo3ln_type='mswg'"));
$type_mo3ln_mktb = mysql_num_rows(mysql_query("SELECT * FROM `tableshow` $weress AND mo3ln_type='mktb'"));
$type_mo3ln_wkeel = mysql_num_rows(mysql_query("SELECT * FROM `tableshow` $weress AND mo3ln_type='wkeel'"));
$type_mo3ln_no = mysql_num_rows(mysql_query("SELECT * FROM `tableshow` $weress AND mo3ln_type='0'"));

进行计数的函数是php 中预定义的函数

我正在考虑使用count()函数,但我想知道是否可以像Hates先生在这里建议的那样,仅对某些特定行使用Sum函数获取MySQL数据库中所有表的记录计数

SELECT COUNT(*) FROM `table` WHERE `whatever`='whatever';

将返回一行(而不是超过9000),其中包含基于您设置的规则的正确计数。

这应该更快:

SELECT COUNT(CASE mo3ln_type WHEN 'malk'  THEN 1 END) AS cnt_mo3ln_malk,
       COUNT(CASE mo3ln_type WHEN 'mswg'  THEN 1 END) AS cnt_mo3ln_mswg,
       COUNT(CASE mo3ln_type WHEN 'mktb'  THEN 1 END) AS cnt_mo3ln_mktb,
       COUNT(CASE mo3ln_type WHEN 'wkeel' THEN 1 END) AS cnt_mo3ln_wkeel,
       COUNT(CASE mo3ln_type WHEN '0'     THEN 1 END) AS cnt_mo3ln_no
FROM   tableshow
WHERE  mo3ln_type IN ('malk', 'mswg', 'mktb', 'wkeel', '0')

这将在一个SELECT语句中获得所有计数,而不是在五个单独的语句中。

假设您在mo3ln_type列上设置了一个索引,WHERE子句应该会很快缩小您的行,那么只需要在COUNT()中有条件地聚合这些行。

如果将每个mo3ln_type表示为整数而不是字符串,则速度会更快,因为对数字的比较要快得多。也许您可以创建另一个表来存储不同的mo3ln_types,在tableshow表中,只需在mo3ln_types中使用一个对INT主键的外键引用,而不是实际的文本字符串。(例如WHERE mo3ln_type_id IN (1, 2, ...)而不是WHERE mo3ln_type IN 'malk', 'mswg', ...)

您可以使用count(*):

SELECT COUNT(*) FROM <table_name> WHERE <where_clause>;

或者(例如,如果您进行分页)使用SQL_CALC_FOUND_ROWS,如果您还想进行查询:

SELECT SQL_CALC_FOUND_ROWS * FROM <table_name> WHERE <clause> LIMIT 0, 10;
SELECT FOUND_ROWS();

更多信息:MySql信息函数->FOUND_ROWS()

如果您只想获得计数,请使用SUM函数:

SELECT SUM(CASE WHEN mo3ln_type = 'malk'  THEN 1 ELSE 0 END) AS malk,
       SUM(CASE WHEN mo3ln_type = 'mswg'  THEN 1 ELSE 0 END) AS mswg,
       SUM(CASE WHEN mo3ln_type = 'mktb'  THEN 1 ELSE 0 END) AS mktb,
       SUM(CASE WHEN mo3ln_type = 'wkeel' THEN 1 ELSE 0 END) AS wkeel,
       SUM(CASE WHEN mo3ln_type = '0'     THEN 1 ELSE 0 END) AS no_type
FROM   tableshow
WHERE  <where_clausw>

更多信息:MySql控制流函数->CASE运算符,MySql聚合函数->SUM函数*

  • dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_sum

数据库预成型的工作速度总是比应用程序层快得多,因此使用Count(*)命令从数据库返回计数的效率要高得多。

要求数据库计算行数,而不是PHP。在SQL语句中使用COUNT(*)。

function f_count_rows($table, $where='') {
  $result = mysql_query("SELECT COUNT(*) AS nbr FROM `".$table."` ".$where);
  $row = mysql_fetch_assoc($result);
  return $row['nbr'];
}
$type_mo3ln_malk  = f_count_rows("tableshow", $weress." AND mo3ln_type='malk'");
$type_mo3ln_mswg  = f_count_rows("tableshow", $weress." AND mo3ln_type='mswg'");
$type_mo3ln_mktb  = f_count_rows("tableshow", $weress." AND mo3ln_type='mktb'");
$type_mo3ln_wkeel = f_count_rows("tableshow", $weress." AND mo3ln_type='wkeel'");
$type_mo3ln_no    = f_count_rows("tableshow", $weress." AND mo3ln_type='0'");