我需要传输数据(我需要的列n.inchi,n.info,n.accessions,n.chebiid
从一个表到另一个表,两个表都有超过20,000行(heroku_chemical_chemical
有50,000个,这就是表I我传输的数据to)。
我尝试了这个查询:
UPDATE heroku_chemical_chemical AS h, new_compounds_filtered AS n
SET
h.inchi_identifier=n.inchi,
h.info=n.info,
h.accessions=n.accessions,
h.chebi_id=n.chebiid
WHERE h.name = n.name
AND (h.inchi_identifier = '' OR h.inchi_identifier IS NULL);
基本上,表1中显示的化学名称(heroku_chemical_chemical
)可能存在于表2中,如果是,我需要从表2中获取该化学品的数据。如果h.inchi_identifier
中有数据,那么我就知道化学品已经完成了。问题是查询需要花费很长时间才能执行,我让它在一夜之间运行,但是第二天早上它仍然没有完成,所以我不得不取消它。自交易以来,没有任何转移。如果它是逐位执行传输,那么它将起作用。
我可以将其添加到查询中:
AND n.id BETWEEN 1 AND 500
将查询限制为500行(从我传输数据的第二个表中)以小块形式执行,但是我手动必须继续使用{{1的不同值重新运行查询子句。它也很慢。我更喜欢在纯SQL中执行此操作,而不是设置PHP脚本。
有没有办法在数据进行时插入数据,而不是等到整个事务完成?另外,有没有办法更快地完成这项工作?
见表定义:
heroku_chemical_chemical
BETWEEN
new_compounds_filtered
CREATE TABLE `heroku_chemical_chemical` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8mb4_unicode_ci,
`synonyms` text COLLATE utf8mb4_unicode_ci,
`associated_from` text COLLATE utf8mb4_unicode_ci,
`category_associated_from` text COLLATE utf8mb4_unicode_ci,
`chemical_number` text COLLATE utf8mb4_unicode_ci,
`parent_chemical_numbers` text COLLATE utf8mb4_unicode_ci,
`category_id` text COLLATE utf8mb4_unicode_ci,
`slug` text COLLATE utf8mb4_unicode_ci,
`cas_rn` text COLLATE utf8mb4_unicode_ci,
`definition` text COLLATE utf8mb4_unicode_ci,
`drug_bank_ids` text COLLATE utf8mb4_unicode_ci,
`foodb_id` text COLLATE utf8mb4_unicode_ci,
`itis_id` text COLLATE utf8mb4_unicode_ci,
`name_scientific` text COLLATE utf8mb4_unicode_ci,
`picture_content_type` text COLLATE utf8mb4_unicode_ci,
`picture_file_name` text COLLATE utf8mb4_unicode_ci,
`picture_file_size` text COLLATE utf8mb4_unicode_ci,
`wikipedia_id` text COLLATE utf8mb4_unicode_ci,
`actor_id` text COLLATE utf8mb4_unicode_ci,
`bio_cyc_id` text COLLATE utf8mb4_unicode_ci,
`chebi_id` text COLLATE utf8mb4_unicode_ci,
`chem_spider_id` text COLLATE utf8mb4_unicode_ci,
`chembl_id` text COLLATE utf8mb4_unicode_ci,
`ctd_id` text COLLATE utf8mb4_unicode_ci,
`hmdb_id` text COLLATE utf8mb4_unicode_ci,
`inchi_identifier` text COLLATE utf8mb4_unicode_ci,
`inchi_key` text COLLATE utf8mb4_unicode_ci,
`kegg_compound_id` text COLLATE utf8mb4_unicode_ci,
`omim_id` text COLLATE utf8mb4_unicode_ci,
`pdb_id` text COLLATE utf8mb4_unicode_ci,
`pubchem_compound_id` text COLLATE utf8mb4_unicode_ci,
`stitch_di` text COLLATE utf8mb4_unicode_ci,
`t3db_id` text COLLATE utf8mb4_unicode_ci,
`uni_prot_id` text COLLATE utf8mb4_unicode_ci,
`iupac_name` text COLLATE utf8mb4_unicode_ci,
`formula` text COLLATE utf8mb4_unicode_ci,
`smiles` text COLLATE utf8mb4_unicode_ci,
`chemspider_id` text COLLATE utf8mb4_unicode_ci,
`molecular_weight` text COLLATE utf8mb4_unicode_ci,
`accessions` text COLLATE utf8mb4_unicode_ci,
`chebi_info` text COLLATE utf8mb4_unicode_ci,
`chebi_name` text COLLATE utf8mb4_unicode_ci,
`compound_type` text COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
AUTO_INCREMENT=379336
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci;
更新
所以我正在运行一个新查询,需要将ID(被索引)加载到关系表的列中。
CREATE TABLE `new_compounds_filtered` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8mb4_unicode_ci,
`chebiid` text COLLATE utf8mb4_unicode_ci,
`info` text COLLATE utf8mb4_unicode_ci,
`smiles` text COLLATE utf8mb4_unicode_ci,
`inchi` text COLLATE utf8mb4_unicode_ci,
`inchikey` text COLLATE utf8mb4_unicode_ci,
`parent_id` text COLLATE utf8mb4_unicode_ci,
`accessions` text COLLATE utf8mb4_unicode_ci,
`synonyms` text COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
AUTO_INCREMENT=85432
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci ;
同样的问题,查询似乎没有完成。我无法在H1.foodb_id上添加唯一索引,因为表中只有大约5%的化学品具有FooDB ID。所以我遇到了同样的问题。 O2.compound_id是未编制索引的,因为它的所有字段现在都是空白的,除非我在每个字段中插入临时唯一编号,否则我无法对它们编制索引。
下面是UPDATE chemical_organism_relations AS O2, heroku_chemical_chemical AS H1
SET O2.compound_id = H1.id, O2.substance_type = 'compound'
WHERE O2.foodb_compound_id = H1.foodb_id;
表中的内容:
我一直在寻找一种方法来跟踪查询进度。我想知道的一件事是这些专栏意味着什么:
有没有办法看到幕后发生的事情?如果我能看到服务器正在做什么以及它在运行查询时取得了多少进展,那么我就知道查询是否会完成,但是现在我不知道它是否崩溃或者是否发生了什么。
我刚刚运行了一个非常简单的查询:
的MySQL> UPDATE chemical_organism_relations SET substance_type = '化合物&#39 ;;查询OK,受影响的740672行(1分钟2.95秒)行 匹配:740672更改:740672警告:0
74000,但需要一分钟来处理一个不涉及其他表的简单更新查询。
我的查询存在大问题 在我将它与主线程合并之前,有人评论了一个答案,他们说是因为:
performance_schema.events_statements_current
我的查询存在很大问题。我不小心发布了错误的查询,但我现在发布了正确的查询,查询仍有问题吗?
答案 0 :(得分:1)
如上所述,50k线真的没什么:在1M之后事情变得严重,你需要思考一下,如果你想超过10M而没有问题......
除此之外,当你做一个大事务时,你需要有点小心,innoDB并没有真正配置为默认值,并且会有一些RAM& I.O磁盘瓶颈(如果必须定期进行,请查看MySQL transaction size - how big is too big?,一些数据库调优可能是一个好主意)
无论如何,让我们从一些基础知识开始:
WHERE
h.name = n.name
AND (
h.inchi_identifier = ''
OR h.inchi_identifier IS NULL
);
大查询中WHERE之后的每个字段应该强制有一个索引如果你不能放一个,那么你的数据库架构是坏的(如果你在0.01中那么可能是99.99%) %你已经知道为什么了)
What Index you ask ?嗯,你有一些选择,我只会解释最有用的一些:
PRIMARY KEY
是的,这是第一个也是最重要的。你只能有一个表,它也是一个UNIQUE
约束,如果你有和标识符字段,使用它作为你的PK,不需要添加专用的id int auto_increment
。
UNIQUE INDEX
如果您的桌子上已经有PK,但在另一个字段中有一些唯一的ID,UNIQUE INDEX
可以帮助您快速阅读/更新此字段(但会减慢插入,因为它会检查唯一性)
INDEX
,多遍“但我已经有PK了,我的字段不是唯一的,所以没有索引?”
在大多数数据库中通常都是这种情况,你有一个外国人密钥(1-N)的字段,你会在其上做很多JOIN
和WHERE
,但不能使用一个之前的指数,然后来了魔术:
INDEX
允许您加快查询速度,即使字段中存在重复项或null 。
它会使INSERT慢一点,但你将获得SELECT,UPDATE,DELETE,WHERE,JOIN和这个字段。
这是制作索引的更多方法。这比以前的更复杂,因为如果你想要使用这个查询,你真的需要了解你的查询是如何工作的。
[以书面形式]
回到你的查询,这可能是你应该做的(记住它可以减慢一些操作,并且可能需要一些时间来构建):
-- speed the null / "" detection
CREATE INDEX idx_hcc_inchi_id_1char
ON heroku_chemical_chemical (inchi_identifier(1));
-- uniqueness of name
CREATE UNIQUE INDEX idx_hcc_name_u
ON heroku_chemical_chemical (name);
CREATE UNIQUE INDEX idx_ncf_name_u
ON new_compounds_filtered (name);
对于问题的第二部分:
“我不能在
UNIQUE INDEX
上放foodb_id
,因为只有5%的行有FooDB_ID”
不是问题:
''
更新为NULL
:UPDATE table SET column=NULL WHERE column='';
UNIQUE INDEX
,因为NULL