繁体   English   中英

在每个页面加载时自动索引,修复和优化MySQL表

[英]Auto index, repair and optimize MySQL table on every page load

我和一个人在辩论,告诉我使用他的功能没有表现出来......

每个运行页面的用户在每个页面加载时使用PHP类__destruct()自动索引,修复和优化MySQL表。

他问我为什么认为这对表现不好但是我真的不知道,有人能告诉我为什么这样的事情不好吗?

更新他的推理......

优化和修复数据库表消除了开销的字节大小,当涉及多个连接和表使用时,这会大大减慢其他查询的速度。 即使启用了索引的性能增强的数据库架构也是如此。

更不用说执行这些操作的执行时间在内存和处理器线程中都是微不足道的。

打开,阅读,写作,更新,然后清理自己对我更有意义,然后执行相同的操作,并在等待cron条目清理后留下不必要的开销。

而不是争论,为什么不衡量? 使用工具包来分析您花时间的位置,例如Instrumentation for PHP 证明PHP请求的优化步骤需要很长时间。

重新索引是一个昂贵的过程,至少与执行表扫描一样昂贵,就好像您没有索引一样。 您应该不经常构建索引,以便在每次构建索引时借助索引提供许多PHP请求。 如果您正在为每个PHP请求构建索引,那么您可能根本不定义索引,并且只是一直运行表扫描。

REPAIR TABLE仅与MyISAM表(和存档表)相关。 我不建议使用MyISAM表。 你应该只使用InnoDB表。 不仅是为了性能,还为了数据安全。 MyISAM非常容易受到数据损坏的影响,而InnoDB在大多数情况下通过维护每页的内部校验和来防止这种情况。

InnoDB表的OPTIMIZE TABLE重建所有数据和索引页面。 一旦你的桌子增长到一个非平凡的大小,这将是非常昂贵的。 当然不是你想要在每个页面加载上做的事情。 我甚至会说你不应该在任何 PHP Web请求期间执行OPTIMIZE TABLE - 通过某些脚本或管理界面离线执行。

表重组也会锁定表。 您将排队访问同一个表的所有其他PHP请求很长时间(即几分钟甚至几小时,具体取决于表的大小)。 当每个PHP请求都有机会时,它将运行另一个表重组。 在每个PHP请求上产生这么多的开销是荒谬的。


您也可以使用类比:您不会在每次PHP请求期间重建或优化整个表或索引,原因与您每次启动时都不会让您的汽车进行调整和换油一样:
这样做既昂贵又不方便,与在适当的时间表上进行发动机维护相比,它没有任何额外的好处。

因为每一项操作(索引,修复和优化)都需要相当长的时间; 事实上,如果表格甚至略大,它们非常昂贵(表锁,磁盘IO,数据丢失的风险)。

绝对不建议在每个页面加载时执行此操作。 它应该只在需要时完成。

修复表可能会导致数据丢失,如文档中所述,因此需要先前的备份以避免进一步的问题。 此外,它仅在灾难发生时运行(HAS失败)。

优化表会阻止维护中的表,因此可能会导致并发用户出现问题。

我的0.02:数据库管理操作不应该是常见用户事务的一部分,因为随着表的增长,它们的时间和资源都很昂贵。

我已经将以下代码设置为每天清晨运行的预定作业,当用户不经常访问我们的站点时(我读到OPTIMIZE应该在优化期间锁定受影响的表)。

使用此函数的优点是单个查询由所有以逗号分隔的表名组成,而是执行大量查询,每个表对应一个优化。

假设您已打开数据库连接并选择了数据库,以便在不指定数据库连接,数据库名称等的情况下使用此功能。

$q = "SHOW TABLE STATUS WHERE Data_Free > '0'";
$res = mysql_query($q); $TOOPT = mysql_num_rows($res);
$N = 0; // number of optimized tables
if(mysql_num_rows($res) > 0)
{
        $N = 1;
        while($t = mysql_fetch_array($res))
        {
            $TNAME = $t['Name']; $TSPACE += $t['Data_free'];
            if($N < 2)
            {
                $Q  = "OPTIMIZE TABLE ".$TNAME."";
            }
            else
            {
                $Q .= ", ".$TNAME."";
            }
            $N++;
        } // endwhile tables
        mysql_query($Q);
} // endif tables found (to optimize)

文件陈述......

优化参考

如果删除了表的大部分,或者对具有可变长度行的表(具有VARCHAR,VARBINARY,BLOB或TEXT列的表)进行了许多更改,则应使用OPTIMIZE TABLE。 删除的行在链表中维护,随后的INSERT操作重用旧的行位置。 您可以使用OPTIMIZE TABLE回收未使用的空间并对数据文件进行碎片整理。 在对表进行大量更改后,此语句还可能会提高使用该表的语句的性能,有时甚至会显着提高。

执行操作时,使用'OPTIMIZE'命令可以提高性能。

刷新参考

FLUSH TABLES有几种变体形式。 FLUSH TABLE是FLUSH TABLES的同义词,除了TABLE不能与WITH READ LOCK变体一起使用。

使用'FLUSH TABLE'命令与'FLUSH TABLES'没有执行READ LOCK。

修理参考

通常,您永远不必运行REPAIR TABLE。 但是,如果发生灾难,此声明很可能会从MyISAM表中获取所有数据。 如果您的表经常损坏,您应该尝试找到它的原因,以消除使用REPAIR TABLE的需要。 请参见第C.5.4.2节“如果MySQL不断崩溃该怎么办”,以及第13.5.4节“MyISAM表问题”。

我的理解是,如果“REPAIR TABLE”命令一致地运行,则在执行常量维护时,将消除有关创建的大记录的条件。 如果我错了,我希望看到基准,因为我自己的尝试没有显示任何太有害的,尽管记录集已经低于10k标记。

以下是正在使用的代码,@ codedev正在询问...

class db
{
 protected static $dbconn;

 // rest of database class

 public function index($link, $database)
 {
  $obj = $this->query('SHOW TABLES');
  $results = $this->results($obj);
  foreach ($results as $key => $value){
   if (isset($value['Tables_in_'.$database])){
    $this->query('REPAIR TABLE '.$value['Tables_in_'.$database]);
    $this->query('OPTIMIZE TABLE '.$value['Tables_in_'.$database]);
    $this->query('FLUSH TABLE '.$value['Tables_in_'.$database]);
   }
  }
 }
 public function __destruct()
 {
  $this->index($this->dbconn, $this->configuration['database']);
  $this->close();
 }
}

暂无
暂无

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

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