加快本地 MySql 以在大表上启动规范化查询

Speed up local MySql to launch normalization query on big tables

我正在规范化 "cleaning" 一个 MySql 数据库,其中最大的 table 计数约 300 万条记录。

我要做的是重命名一些字段(非常快),更改它们的顺序(非常快),然后做一些 trim、字符串清理、将一些字段提取到其他字段 table s 并保留外键 ID...

有什么方法可以加快本地计算机上的查询速度吗?

我在 MacBook Air 8GB Ram 上安装了 MariaDB 10.1.21(来自 XAMPP)和 运行。

我已经在很多字段上设置了索引,但它仍然像乌龟一样慢。

如有任何提示,我们将不胜感激。谢谢!

编辑:根据要求提供更多信息和我正在执行的一些优化。

我基本上有一个很大的 table,其中包含未规范化的列,这些列通常会分布在三个 table 中。

我有:

companies ( id, name, street, city_name, category_name, subcategory_name )

我想要的

companies ( id, name, street, id_city, id_subcategory, ... )
cities( id, name, ... )
categories( id, name )
subcategories( id, name, id_category )

所以我清理并提取数据如下。

Trim 并从 "dirty" 字段中清理运输 returns:

update companies set mic_cat = TRIM(REPLACE(REPLACE(mic_cat, '\r', ''), '\n', ''));

删除类别不正确的公司。

delete from companies where mic_cat is null or mic_cat = '' or mac_cat is null or mac_cat = '';

从字段中提取数据并放入新的 tables:

insert into categories (name) select distinct mac_cat from companies;
insert into subcategories (name, id_category) select distinct mic_cat,categories.id from companies JOIN categories ON mac_cat = categories.name;

添加id_reference:

ALTER TABLE companies ADD COLUMN id_subcategory int;

拿到钥匙...

UPDATE companies left join subcategories on companies.mic_cat = subcategories.name set id_subcategory = subcategories.id;

最后一个很慢,所以,我放弃了所有索引,然后在companies.mic_cat和subcategories.name上只创建两个索引,它已经固定了很多。

  • 在单个 UPDATE 语句中完成所有更新。
  • 如果您需要修改索引中的列,请先 DROP 那些索引,然后再 ADD 返回。 (这可能有帮助。)
  • 在单个 ALTER 语句中完成所有 ALTERs。 (这并不总是最好的建议。)
  • 考虑按行块进行更新。

上面试图解决的一些问题:

  • UPDATE 没有 WHERE 子句(有时带有 WHERE)将扫描整个 table,成本相当高。
  • 修改索引列时,索引中的行需要从索引中的一个位置删除并添加到另一个位置。将其视为 DELETE 加上 INSERT——相当昂贵。
  • ALTER 可能会也可能不会完成 "in place" 的工作。如果你的多个改变不能那样做,那么最好做一个单一的副本(即一个单一的ALTER)来同时做所有的改变。它有效地创建了一个新的空 table,对其进行了更改,将所有数据复制到其中,重新创建了所有索引,然后将其重命名回原位。

关于索引的更多信息...

  • 不要索引标志;这样的索引将被避开。
  • 查看您的 WHERE 子句,了解哪些索引有用。
  • 了解 'composite' 索引:INDEX(a,b) 可能 INDEX(a), INDEX(b) 好得多 一些 查询。
  • 不要盲目地索引每一列——这是一种很大的浪费。

3M 行可能很多。在很多情况下,在"chunks"中UPDATE(或DELETE)更好。参见 my blog