物理磁盘重写mysql数据

时间:2019-07-09 15:29:16

标签: mysql

我多年来第一次使用mysql来帮助一位朋友。问题是:一个mysql表使用INT和CHAR值进行了大量更新。该Web应用程序站点托管在大型通用提供程序上,因此我无法直接控制setup / parameters / etc。该表的性能确实非常糟糕,以至于处理一个数据页最多需要10秒,有时甚至需要15分钟。

我最初尝试将所有更新作为一个事务运行,而不是在Web应用程序(几年前编写)的php循环中运行50ish语句。问题,至少在我看来,问题是该应用程序在带有许多其他通用网站的巨型mysql实例上运行,并且磁盘速度无法处理如此多的更新。

我可以在此提供程序上使用chron / batch作业。该Web应用主要在工作时间使用,因此我可以限制在通宵时间访问Web应用。

我通常使用postgresql或ms sql服务器,因此我对mysql的了解非常有限。

如果我强制将表放下并在一夜之间重写,会提高性能吗?有一些MySQL函数,例如postgres的vacuum吗?我试图搜索信息,但是不幸的是,使用诸如rewrite table之类的词只会带来对sql语法助手或性能调整的引用。

或者,我想我可以在mysql中创建一个新的存储机制,只要它可以通过php脚本完成即可。对于频繁更新的内容,是否有比默认存储引擎更好的存储模式?

2 个答案:

答案 0 :(得分:0)

mysql的性能取决于多种因素,它的复杂程度足以在每种情况下都给出明确的答案。我认为我们可以检查以下步骤,以帮助确定将INSERT数据转化为mysql的方法。

数据库引擎。

您可以使用5种引擎,具体取决于您的用途:MyISAM,内存,InnoDB,存档,NDB。

Document

  • Locking granularitytable的引擎将比其值为row的引擎慢,因为它会在插入或更新单个记录时阻止表更改,而{ {1}}与Locking granularity相同,表示在插入或更新记录时仅锁定该行。
  • 执行rowINSERT记录时,具有UPDATE属性的引擎会变慢,因为必须重建索引,因此您可以更快地进行B-tree indexes查询。因此,表中索引的数量也会降低插入和更新速度。
  • 索引为SELECT的索引将比索引索引CHAR慢,因为要花更多的时间来找出在哪里找到在INT中存储数据的正确节点。

MYSQL语句

MYSQL的估算系统可通过在您的mysql语句前添加EXPLAIN来帮助您发现查询的性能。

示例

mysql

Document

答案 1 :(得分:0)

我在一个Web应用程序上工作,在该应用程序中,我们使用mysql(这真的很好!)来扩展非常大的数据。

除了@Lam Nguyen在他的回答中所说的,这里没有什么要考虑的,

  1. 检查您正在使用哪个MySQL引擎,以查看它在selectinsertupdate期间获得了哪些锁。要检查您正在使用的引擎,这里是一个示例查询,您可以使用该查询运行石蕊测试。

mysql> show table status where name="<your_table_name>";
+-------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------+
| Name  | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time         | Update_time | Check_time | Collation          | Checksum | Create_options | Comment |
+-------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------+
| Login | InnoDB |      10 | Dynamic    |    2 |           8192 |       16384 |               0 |            0 |         0 |           NULL | 2019-04-28 12:16:59 | NULL        | NULL       | utf8mb4_general_ci |     NULL |                |         |
+-------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+--------------------+----------+----------------+---------+

mysql安装随附的默认引擎为InnoDB。插入行时,InnoDB不会获得任何锁定。

  • SELECT ... FROM是一致的读取,读取数据库快照并且不设置锁定,除非将事务隔离级别设置为SERIALIZABLE。

  • 锁定读取,UPDATE或DELETE通常会对在处理SQL语句时扫描的每个索引记录设置记录锁定。

InnoDB lock sets

  1. 检查要索引的列。为您确实会查询很多的列建立索引。避免索引char列。

要检查表中哪些列已建立索引,

mysql> show index from BookStore2;
+------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table      | Non_unique | Key_name       | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Bookstore2 |          0 | PRIMARY        |            1 | ISBN_NO     | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| Bookstore2 |          1 | SHORT_DESC_IND |            1 | SHORT_DESC  | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
| Bookstore2 |          1 | SHORT_DESC_IND |            2 | PUBLISHER   | A         |           0 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
3 rows in set (0.03 sec)

  1. 不要对表中的大数据集运行内部查询。要真正查看您的查询在查询上运行了什么explain,并查看迭代的行数

mysql> explain select * from login;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | login | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.03 sec)

  1. 避免连接表。
  2. 确保您要在条件中使用主键进行查询,或者至少要在索引列中进行查询。
  3. 当表太大时,请确保将其拆分为多个集群。

只需进行一些调整,我们仍然可以在最短的时间内获得查询结果。