加快本地 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。
我正在规范化 "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。