简体   繁体   English

在大表上优化计数SQL查询

[英]Optimize a count SQL query on a big table

I have a table with over 10 thousand registers right now, and they start to run so slow. 我现在有一个表,其中有超过1万个寄存器,它们开始运行得非常慢。

I have the following code: 我有以下代码:

COUNT 计数

$SqlCount = "SELECT tabnews.New_Id
            FROM tabnew WHERE New_Id <> '' AND New_Status = 1";
$QueryCount = mysql_query($SqlCount, $Conn) or die(mysql_error($Conn));
$NumCount = mysql_num_rows($QueryCount);
$recordCount = $NumCount;

PAGINATION 分页

if (!$id) $p = 1;
else $p = $id;
$pageSize = 16;
$itemIni = ($pageSize*$p)-$pageSize;
$totalPage = ceil($recordCount/$pageSize);

SHOW 节目

       $Sql52 = "SELECT New_Id, New_Nome, New_Data, New_Imagem FROM tabnews WHERE New_Status = 1 ORDER BY New_Id DESC LIMIT $itemIni, $pageSize ";
       $Query52 = mysql_query($Sql52, $Conn);
       while($Rs52 = mysql_fetch_array($Query52)){

      // ECHO RESULTS
}

MY DATABASE: 我的数据库:

CREATE TABLE IF NOT EXISTS `tabnews` (
  `New_Id` int(11) NOT NULL AUTO_INCREMENT,
  `Franquia_Id` text NOT NULL,
  `New_Slide` int(2) NOT NULL,
  `Categoria_Id` int(2) NOT NULL,
  `New_Nome` varchar(255) NOT NULL,
  `New_Data` date NOT NULL,
  `New_Imagem` varchar(75) NOT NULL,
  `New_Status` int(11) NOT NULL,
  PRIMARY KEY (`New_Id`),
  KEY `idx_1` (`New_Status`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10490 ;

Any ideas on how I can make this run faster? 关于如何使运行速度更快的任何想法?

I have a dedicated server running CENTOS. 我有一台运行CENTOS的专用服务器。

20 seconds is very weird for such a little table. 这么小的桌子20秒非常奇怪。 I have a very similar table with almost 4 million rows and your both SQL statements takes less than 0.002 sec. 我有一个非常相似的表,几乎有400万行,并且您的两个SQL语句都花费不到0.002秒。

CREATE TABLE IF NOT EXISTS `tasks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `status` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'open',
  `method` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'GET',
  `url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `params` text COLLATE utf8_unicode_ci,
  `response` text COLLATE utf8_unicode_ci,
  `executed_by` varchar(50) COLLATE utf8_unicode_ci DEFAULT '',
  `execute_at` datetime DEFAULT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `status` (`status`),
  KEY `modified` (`modified`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3839270 ;

- -

SELECT COUNT(id) FROM tasks WHERE status='done';
---> Query took 0.0008 sec

- -

SELECT id, status, method, url FROM tasks WHERE status='done' ORDER BY id DESC LIMIT 200, 100;
---> Query took 0.0011 sec

Observations: 观察:

  • You should use SELECT COUNT(New_Id)... 您应该使用SELECT COUNT(New_Id)...
  • New_id <> '' doesn't make sense. New_id <>''没有意义。 New_id can't be empty or NULL New_id不能为空或NULL
  • Set the length of New_Status to something that match the values you store there 将New_Status的长度设置为与您存储在其中的值匹配的长度
  • Try turning off logging: SET GLOBAL general_log = 'OFF'; 尝试关闭日志记录:SET GLOBAL general_log ='OFF';
  • Update your server packages (specially MySQL) 更新您的服务器软件包(特别是MySQL)
  • Is it a dedicated server only for the database? 它是仅用于数据库的专用服务器吗?
  • Is the server running other things? 服务器正在运行其他东西吗? (run 'top' and 'uptime' to check it status) (运行“ top”和“ uptime”以检查其状态)

This: 这个:

New_Id <> '' 

What does this do? 这是做什么的? It casts every single one of your INT primary key to string to compare it to a string. 它将INT主键的每个单个键都转换为字符串,以将其与字符串进行比较。 Why would you compare it to a string? 为什么它与字符串进行比较? It cannot be '' by definition, omit that New_Id <> '' from your WHERE clause. 根据定义,它不能'' ,请从WHERE子句中省略New_Id <> ''

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM