Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何提高MySQL查询执行速度_Php_Mysql_Sql_Sql Insert_Recursive Query - Fatal编程技术网

Php 如何提高MySQL查询执行速度

Php 如何提高MySQL查询执行速度,php,mysql,sql,sql-insert,recursive-query,Php,Mysql,Sql,Sql Insert,Recursive Query,您必须填写表格1至1000000: Table view CREATE TABLE `test` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , `value` INT UNSIGNED NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;" 我写了一个函数来实现这一点,但是向表中添加数据太慢了,如何提高插入数据的性能 function InsertData(){ global $MySQ

您必须填写表格1至1000000:

Table view
CREATE TABLE `test` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , `value` INT UNSIGNED NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;"
我写了一个函数来实现这一点,但是向表中添加数据太慢了,如何提高插入数据的性能

function InsertData(){

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

    $MySQL->close();
}

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

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行,然后将这些行相乘:

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

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

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行,然后将这些行相乘:

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

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

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限制,这对于单个事务来说太多,您可以每隔大约10000次插入执行一次提交:

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();
}
请注意最终限制->


当然,这是一个实验或一次脚本。不建议在生产数据库中执行此操作。

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

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限制,这对于单个事务来说太多,您可以每隔大约10000次插入执行一次提交:

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();
}
请注意最终限制->

当然,这是一个实验或一次脚本。不建议在生产数据库中执行此操作。

尝试此查询:

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等。下面是它的工作原理:

表t1、t2、t3、t4、t5、t6各为10行。交叉连接它们会生成10^6=1000000个组合,因此生成的表将包含一百万行; 对于每一行,我们选择@row变量两次。不仅如此,我们还用1来增加它; nums表仅用于在开始时将变量初始化为0; 生成的表被传递给INSERT语句,数据存储在表中。 一个看起来更干净的解决方案是将递归CTE与较新的MySQL/MariaDB结合使用。它是:

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

请尝试以下查询:

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等。下面是它的工作原理:

表t1、t2、t3、t4、t5、t6各为10行。交叉连接它们会生成10^6=1000000个组合,因此生成的表将包含一百万行; 对于每一行,我们选择@row变量两次。不仅如此,我们还用1来增加它; nums表仅用于在开始时将变量初始化为0; 生成的表被传递给INSERT语句,数据存储在表中。 一个看起来更干净的解决方案是将递归CTE与较新的MySQL/MariaDB结合使用。它是:


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

不幸的是,我不能在5秒以上使用MySQL递归解决方案很好-它与我在下面发布的变量方法相当递归只是稍微慢了一点:8秒,而我的计算机上是6.5秒。然而,第二个非常慢,1分钟18秒。不幸的是,我不能在5秒以上使用MySQL递归解决方案很好-它与我在下面发布的变量方法相比,递归只是慢了一点:8秒,而我的计算机上是6.5秒。然而,第二个是非常缓慢的1分18秒。