简体   繁体   English

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

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

I am in a debate with a guy telling me that there is no performance hit for using his function that... 我和一个人在辩论,告诉我使用他的功能没有表现出来......

Auto index, repair and optimize MySQL tables using PHP class __destruct() on every single page load by every user who runs the page. 每个运行页面的用户在每个页面加载时使用PHP类__destruct()自动索引,修复和优化MySQL表。

He is asking me why I think it is not good for performance but I do not really know, can someone tell me why such a thing isn't good? 他问我为什么认为这对表现不好但是我真的不知道,有人能告诉我为什么这样的事情不好吗?

UPDATE His reasoning... 更新他的推理......

Optimizing & repairing the database tables eliminates the byte size of overhead that can essentially slow down additional queries when multiple connections and table use are concerned. 优化和修复数据库表消除了开销的字节大小,当涉及多个连接和表使用时,这会大大减慢其他查询的速度。 Even with a performance enhanced database schema with indexing enabled. 即使启用了索引的性能增强的数据库架构也是如此。

Not to mention the amount of execution time to perform these operations are slim to none in memory and processor threading. 更不用说执行这些操作的执行时间在内存和处理器线程中都是微不足道的。

Opening, reading, writing, updating and then cleaning up after oneself makes more sense to me then performing the same operations and leaving unnecessary overhead behind waiting for a cron entry to clean up. 打开,阅读,写作,更新,然后清理自己对我更有意义,然后执行相同的操作,并在等待cron条目清理后留下不必要的开销。

Instead of arguing, why not measure? 而不是争论,为什么不衡量? Use a toolkit to profile where you're spending time, such as Instrumentation for PHP . 使用工具包来分析您花时间的位置,例如Instrumentation for PHP Prove that the optimize step of your PHP request is taking a long time. 证明PHP请求的优化步骤需要很长时间。

Reindexing is an expensive process, at least as costly as doing a table-scan as if you did not have an index. 重新索引是一个昂贵的过程,至少与执行表扫描一样昂贵,就好像您没有索引一样。 You should build indexes infrequently, so that you serve many PHP requests with the aid of the index for every one time you build the index. 您应该不经常构建索引,以便在每次构建索引时借助索引提供许多PHP请求。 If you're building the index on every PHP request, you might as well not define indexes at all, and just run table-scans all the time. 如果您正在为每个PHP请求构建索引,那么您可能根本不定义索引,并且只是一直运行表扫描。

REPAIR TABLE is only relevant for MyISAM tables (and Archive tables). REPAIR TABLE仅与MyISAM表(和存档表)相关。 I don't recommend using MyISAM tables. 我不建议使用MyISAM表。 You should just use InnoDB tables. 你应该只使用InnoDB表。 Not only for the sake of performance, but also data safety. 不仅是为了性能,还为了数据安全。 MyISAM is very susceptible to data corruption, whereas InnoDB protects against that in most cases by maintaining internal checksums per page. MyISAM非常容易受到数据损坏的影响,而InnoDB在大多数情况下通过维护每页的内部校验和来防止这种情况。

OPTIMIZE TABLE for an InnoDB table rebuilds all the data and index pages. InnoDB表的OPTIMIZE TABLE重建所有数据和索引页面。 This is going to be immensely expensive once your table grows to a non-trivial size. 一旦你的桌子增长到一个非平凡的大小,这将是非常昂贵的。 Certainly not something you would want to do on every page load. 当然不是你想要在每个页面加载上做的事情。 I would even say you should not do OPTIMIZE TABLE during any PHP web request -- do it offline via some script or admin interface. 我甚至会说你不应该在任何 PHP Web请求期间执行OPTIMIZE TABLE - 通过某些脚本或管理界面离线执行。

A table restructure also locks the table. 表重组也会锁定表。 You will queue up all other PHP requests that access the same table for a long time (ie minutes or even hours, depending on the size of the table). 您将排队访问同一个表的所有其他PHP请求很长时间(即几分钟甚至几小时,具体取决于表的大小)。 When each PHP request gets its chance, it'll run another table restructure. 当每个PHP请求都有机会时,它将运行另一个表重组。 It's ridiculous to incur this amount of overhead on every PHP request. 在每个PHP请求上产生这么多的开销是荒谬的。


You can also use an analogy: you don't rebuild or optimize an entire table or index during every PHP request for the same reason you don't give your car a tune-up and oil change every time you start it: 您也可以使用类比:您不会在每次PHP请求期间重建或优化整个表或索引,原因与您每次启动时都不会让您的汽车进行调整和换油一样:
It would be expensive and inconvenient to do so, and it would give no extra benefit compared to performing engine maintenance on an appropriate schedule. 这样做既昂贵又不方便,与在适当的时间表上进行发动机维护相比,它没有任何额外的好处。

Because every single operation (index,repair and optimize) takes considerable time; 因为每一项操作(索引,修复和优化)都需要相当长的时间; in fact they are VERY expensive (table locks, disk IO, risk of data loss) if the tables are even slightly big. 事实上,如果表格甚至略大,它们非常昂贵(表锁,磁盘IO,数据丢失的风险)。

Doing this on every page load is definitely not recommended. 绝对不建议在每个页面加载时执行此操作。 It should be done only when needed. 它应该只在需要时完成。

Repair table could cause data loss as stated in documentation, so it requires previous backup to avoid further problems. 修复表可能会导致数据丢失,如文档中所述,因此需要先前的备份以避免进一步的问题。 Also, it is intended to be run only in case of disaster (something HAS failed). 此外,它仅在灾难发生时运行(HAS失败)。

Optimize table blocks the table under maintenance so it could cause problems to concurrent users. 优化表会阻止维护中的表,因此可能会导致并发用户出现问题。

My 0.02: Database management operations should not be part of common user transactions as they are expensive in time and resources as your tables grow. 我的0.02:数据库管理操作不应该是常见用户事务的一部分,因为随着表的增长,它们的时间和资源都很昂贵。

I have set the following code into our scheduled job running every early morning, when users don't access frequently our site (I read that OPTIMIZE should lock affected tables during optimization). 我已经将以下代码设置为每天清晨运行的预定作业,当用户不经常访问我们的站点时(我读到OPTIMIZE应该在优化期间锁定受影响的表)。

Advantage using this function is that a single query is composed with all table names comma-separated, instead executing a lot of queries, one for each table to optimize. 使用此函数的优点是单个查询由所有以逗号分隔的表名组成,而是执行大量查询,每个表对应一个优化。

It's supposed that you have a db connection opened and a db selected yet, in order to use this function without specifying db connection, db name, etc. 假设您已打开数据库连接并选择了数据库,以便在不指定数据库连接,数据库名称等的情况下使用此功能。

$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)

The docs states... 文件陈述......

( optimize reference ) 优化参考

OPTIMIZE TABLE should be used if you have deleted a large part of a table or if you have made many changes to a table with variable-length rows (tables that have VARCHAR, VARBINARY, BLOB, or TEXT columns). 如果删除了表的大部分,或者对具有可变长度行的表(具有VARCHAR,VARBINARY,BLOB或TEXT列的表)进行了许多更改,则应使用OPTIMIZE TABLE。 Deleted rows are maintained in a linked list and subsequent INSERT operations reuse old row positions. 删除的行在链表中维护,随后的INSERT操作重用旧的行位置。 You can use OPTIMIZE TABLE to reclaim the unused space and to defragment the data file. 您可以使用OPTIMIZE TABLE回收未使用的空间并对数据文件进行碎片整理。 After extensive changes to a table, this statement may also improve performance of statements that use the table, sometimes significantly. 在对表进行大量更改后,此语句还可能会提高使用该表的语句的性能,有时甚至会显着提高。

When operations have been performed performance is enhanced by using the 'OPTIMIZE' command. 执行操作时,使用'OPTIMIZE'命令可以提高性能。

( flush reference ) 刷新参考

FLUSH TABLES has several variant forms. FLUSH TABLES有几种变体形式。 FLUSH TABLE is a synonym for FLUSH TABLES, except that TABLE does not work with the WITH READ LOCK variant. FLUSH TABLE是FLUSH TABLES的同义词,除了TABLE不能与WITH READ LOCK变体一起使用。

Using the 'FLUSH TABLE' command vs. 'FLUSH TABLES' there is no READ LOCK performed. 使用'FLUSH TABLE'命令与'FLUSH TABLES'没有执行READ LOCK。

( repair reference ) 修理参考

Normally, you should never have to run REPAIR TABLE. 通常,您永远不必运行REPAIR TABLE。 However, if disaster strikes, this statement is very likely to get back all your data from a MyISAM table. 但是,如果发生灾难,此声明很可能会从MyISAM表中获取所有数据。 If your tables become corrupted often, you should try to find the reason for it, to eliminate the need to use REPAIR TABLE. 如果您的表经常损坏,您应该尝试找到它的原因,以消除使用REPAIR TABLE的需要。 See Section C.5.4.2, “What to Do If MySQL Keeps Crashing”, and Section 13.5.4, “MyISAM Table Problems”. 请参见第C.5.4.2节“如果MySQL不断崩溃该怎么办”,以及第13.5.4节“MyISAM表问题”。

It is my understanding here that if the 'REPAIR TABLE' command is run consistantly the condition concerning large records created would be eliminated as constant maintances is performed. 我的理解是,如果“REPAIR TABLE”命令一致地运行,则在执行常量维护时,将消除有关创建的大记录的条件。 If I am wrong I would like to see benchmarks as my own attempts have not shown anything too detrimental, although the record sets have been under the 10k mark. 如果我错了,我希望看到基准,因为我自己的尝试没有显示任何太有害的,尽管记录集已经低于10k标记。

Here is the pice of code that is being used and @codedev is asking about... 以下是正在使用的代码,@ 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