首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何加快查询执行MySQL

问如何加快查询执行MySQL
EN

Stack Overflow用户
提问于 2020-11-02 22:01:45
回答 3查看 317关注 0票数 1

您必须填写表1至表1,000,000:

代码语言:javascript
复制
Table view
CREATE TABLE `test` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , `value` INT UNSIGNED NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;"

我编写了一个函数来完成这个任务,但是将数据添加到表中太慢了,如何提高insert数据的性能?

代码语言:javascript
复制
function InsertData(){

    global $MySQL;
    for($i = 1; $i != 1000000; $i++){
        $MySQL->query("INSERT INTO `name` (`id`, `value`) VALUES ($i, $i);");
    }

    $MySQL->close();
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-11-02 22:23:37

您可以使用事务,以便每千次插入只提交一次(或者,如果您勇敢的话,在百万次查询之后)。下面是(勇敢的)例子:

代码语言:javascript
复制
function InsertData(){
   global $MySQL;

   // Start transactions
   $MySQL->query('SET autocommit=0;');
   $MySQL->query('START TRANSACTION;');

   for($i = 1; $i != 1000000; $i++){
      $MySQL->query("INSERT INTO `name` (`id`, `value`) VALUES ($i, $i);");
   }
   // So far, nothing as actually been saved to database
  
   // Commit all inserts.
   $MySQL->query('COMMIT;');
   $MySQL->query('SET autocommit=1;');

   $MySQL->close();
}

如果由于某些MySQL限制,这对于单个事务来说太大了,那么您可以每10.000次插入一次提交:

代码语言:javascript
复制
function InsertData(){
   global $MySQL;

   // Start transactions
   $MySQL->query('SET autocommit=0;');
   $MySQL->query('START TRANSACTION;');

   for($i = 1; $i != 1000000; $i++){
      $MySQL->query("INSERT INTO `name` (`id`, `value`) VALUES ($i, $i);");
      if($i % 10000 == 0) {
         $MySQL->query('COMMIT;');
         $MySQL->query('START TRANSACTION;');
      }
   }
   // So far, nothing as actually been saved to database
  
   // Commit all inserts.
   $MySQL->query('COMMIT;');
   $MySQL->query('SET autocommit=1;');

   $MySQL->close();
}

注意-> https://stackoverflow.com/a/2298325/2814721的最终极限

当然,这是一个实验或者一次拍摄的剧本。不建议在生产数据库中这样做。

票数 2
EN

Stack Overflow用户

发布于 2020-11-02 22:04:23

如何使用递归CTE将逻辑移动到数据库?

代码语言:javascript
复制
insert into name (id, value)
with recursive cte as (
    select 1 id
    union all select id + 1 from cte where i < 1000000
)
select id, id from cte

这可能是要用递归同时生成的行数。另一种方法是只生成10行,然后乘以这些行:

代码语言:javascript
复制
insert into name (id, value)
with recursive cte as (
    select 0 id
    union all select id + 1 from cte where i < 9
)
select id, id 
from (
    select 1 + c0.id + c1.id * 10 + c2.id * 100 + c3.id * 1000 + c4.id * 10000 + c5.id * 100000 id
    cte c0
    cross join cte c1
    cross join cte c2
    cross join cte c3
    cross join cte c4
    cross join cte c5
) t
票数 2
EN

Stack Overflow用户

发布于 2020-11-02 22:44:25

请尝试以下查询:

代码语言:javascript
复制
INSERT INTO `test` (`id`, `value`) 
SELECT @row := @row + 1 AS row, @row 
FROM (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS t1,
     (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS t2, 
     (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS t3, 
     (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS t4, 
     (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS t5, 
     (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS t6, 
     (SELECT @row:=0) AS nums;

是“插入.选择.”语句类型,其中SELECT语句本身生成百万行,其中填充对(1,1),(2,2)等。下面是它的工作方式:

  1. 表t1、t2、t3、t4、t5、t6各为10行。交叉连接它们将生成10^6 = 1000000的组合,因此生成的表将包含百万行;对于其中的每一行,我们将选择两次@row变量。不仅如此,我们还用1来增加它;

,

  1. ,nums表在开始时只用于将变量初始化为0;
  2. ,结果表被传递给INSERT语句,数据存储在表中。

一个更清晰的解决方案是在更新的MySQL/MariaDB中使用递归CTE。是the one that was submitted by user GMB

代码语言:javascript
复制
INSERT INTO test (id, value)
WITH RECURSIVE temp AS (
    SELECT 1 AS row
    UNION SELECT row + 1 
    FROM temp
    WHERE row < 1000000
)
SELECT row, row
FROM temp;

根据我的测试,速度有点慢。我没有监控内存的使用情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64653950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档