MySQL-如何逐点执行事务,而不是一次执行所有事务(如循环)
我需要将数据(我需要的列是MySQL-如何逐点执行事务,而不是一次执行所有事务(如循环),mysql,sql,Mysql,Sql,我需要将数据(我需要的列是n.inchi,n.info,n.accessions,n.chebiid从一个表传输到另一个表,两个表都有20000多行(heroku_chemical有50000行,这就是我要将数据传输到的表) 我尝试了以下查询: UPDATE heroku_chemical_chemical AS h, new_compounds_filtered AS n SET h.inchi_identifier=n.inchi, h.info=n.info, h.accessions=
n.inchi,n.info,n.accessions,n.chebiid
从一个表传输到另一个表,两个表都有20000多行(heroku_chemical
有50000行,这就是我要将数据传输到的表)
我尝试了以下查询:
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\u chemical\u chemical
)可能出现在表2中,如果是,我需要从表2中获取该化学品的数据。如果h.inchi_identifier
中有数据,那么我知道该化学品已经完成。问题是查询需要花费非常长的时间来执行,我让它运行了一夜,但第二天早上它仍然没有完成,所以我不得不取消它。因为它是一个trAnAction,未传输任何内容。如果它改为逐位执行传输,则它将工作
我可以将其添加到查询中:
AND n.id BETWEEN 1 AND 500
要将查询限制为500行(从我传输数据的第二个表开始),请将其分成小块进行,但随后我必须手动为BETWEEN
子句使用不同的值重新运行查询。这也非常慢。我更喜欢在纯SQL中执行此操作,而不是设置PHP脚本
有没有一种方法可以在执行过程中插入数据,而不是等待整个事务完成?还有,有没有一种方法可以更快地做到这一点
以下是表格定义:
heroku\u chemical\u chemical
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;
新的\u化合物\u过滤
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 ;
更新:
因此,我正在运行一个新的查询,该查询需要将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;
同样的问题,查询似乎没有完成。我无法在H1.foodb_id上放置唯一索引,因为表中只有大约5%的化学品具有foodb id。所以我也有同样的问题。O2.component_id没有索引,因为它的所有字段现在都是空的,除非我在ea中插入一个临时唯一编号,否则我无法为它们编制索引他们中的一个
以下是性能模式中的内容。事件\u语句\u当前的表:
我一直在寻找一种跟踪查询运行进度的方法。我想知道的是这些列的含义:
有没有办法看到幕后发生了什么?如果我能看到服务器在做什么,以及它在运行查询方面取得了多大进展,那么我就知道查询是否会完成,但现在我不知道它是否崩溃或发生了什么
我刚刚运行了一个非常简单的查询:
mysql>更新化学与生物体与物质类型的关系集=
“复合”;查询正常,740672行受影响(1分钟2.95秒)行
匹配:740672更改:740672警告:0
74000,但只需一分钟即可处理一个不涉及其他表的简单更新查询
我的查询有大问题
在我将答案与主线程合并之前,有人对答案发表了评论,他们说因为:
O2.compound_id is unindexed because all of its fields are blank
我的查询有一个大问题。我无意中发布了错误的查询,但我现在发布了正确的查询,查询是否仍然存在大问题?如前所述,50k行真的没什么:1米后事情会变得很严重,如果你想在没有问题的情况下超过10米,你需要考虑一下
除此之外,当您执行单个大型事务时,您需要小心一点,innoDB并没有真正为此进行默认配置,并且会有一些RAM和I.O磁盘瓶颈(如果您必须定期执行,请看一看,一些DB调优可能是个好主意)
无论如何,让我们从一些基本知识开始:
WHERE
h.name = n.name
AND (
h.inchi_identifier = ''
OR h.inchi_identifier IS NULL
);
在大查询中,WHERE后面的每个字段都必须有一个索引,如果您不能放入索引,那么您的DB模式就不好(比如可能是99.99%,如果您处于0.01%的范围内,您已经知道原因)
好吧,你有一些选择,我只解释一下最有用的:
主键
是的,这是第一个也是最重要的。你只能有一个by table,它也是一个唯一的
约束,如果你有和标识符字段,将其用作你的主键,不需要添加一个专用的id int自动增量
1
唯一索引
如果您的表上已经有一个PK,但在另一个字段中有一些唯一的id,unique INDEX
可以帮助您快速读取/更新此字段(但减慢插入速度,因为它会检查唯一性)
索引
,多通道
“但是我已经有了PK,而且我的字段不是唯一的,所以没有索引?”
在大多数数据库中通常都是这样,你有一个外国人键(1-N)的字段,你会让许多加入和其中,但不能使用前面的一个索引,然后神奇的是:
索引
允许您加快查询速度,即使字段中存在重复项或空值
这会使插入速度减慢一点,但您可以通过选择、更新、删除、在何处加入此字段来获得收益
综合指数
这更像是一种建立索引的方法。这比以前的方法更复杂,因为如果你想使用这个方法,你真的需要了解你的查询是如何工作的
[书面形式]
回到您的查询,这可能是您应该做的(请记住,它可能会减慢一些操作,并且可能需要一些时间来构建):
关于问题的第二部分:
“我无法在foodb\u id
上放置唯一索引,因为只有5%的行具有foodb\u id”
没问题:
- (如果我查看您的模式,已经可以了)
- 将空字符串
''
更新为NULL
:更新表集column=NULL,其中column='';
- 在列上添加一个
唯一索引
,因为内部允许NULL
只有50000行?这不会花那么长时间。秒,o
-- 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);