2012-02-20 2 views
1

J'utilise MySQL. Le moteur de tables est MyIsammysql Opérateur "IN" pour supprimer quelques lignes ou quelques requêtes? Lequel est plus vite?

Quelle est la méthode la plus rapide?

DELETE FROM TABLE WHERE id IN (1,2,3); 

ou

DELETE FROM TABLE WHERE id = 1; 
DELETE FROM TABLE WHERE id = 2; 
DELETE FROM TABLE WHERE id = 3; 

champ id est le principal KEY

Lequel va travailler plus vite?

+3

Pourquoi ne pas simplement essayer? –

+1

Chaque fois que vous voulez demander _is x plus vite que y_, la première chose à faire est de la tester par vous-même! –

+0

Définitivement en utilisant IN. –

Répondre

5

IN devrait être plus rapide, car mysql mettra à jour vos index et déplacera les blocs de données après chaque requête dans votre deuxième solution, alors que cela n'arrivera qu'une seule fois avec la première requête.

Et voici quelques tests sur MySQL (pour une table ayant une colonne int et 3 varchars, peuplés avec des données aléatoires et sur l'index sur une colonne dans le WHERE ... n'a pas de sens sans index, car il faut beaucoup plus de temps dans les deux cas ... mais encore un peu plus lent avec 3 requêtes que IN).

mysql> call prepare_data(); 
Query OK, 1 row affected (34.25 sec) 

mysql> delete from t1 where trt in (5, 6, 7); 
Query OK, 300049 rows affected (5.25 sec) 

mysql> call prepare_data(); 
Query OK, 1 row affected (35.18 sec) 

mysql> delete from t1 where trt=5;delete from t1 where trt=6;delete from t1 where trt=7; 
Query OK, 99961 rows affected (2.25 sec) 

Query OK, 99842 rows affected (2.38 sec) 

Query OK, 99558 rows affected (2.69 sec) 

mysql> 

Ainsi, ces trois requêtes, ont beaucoup plus de temps 7.39s vs 5.25s pour IN, ce qui est une augmentation de 40%). Voici la procédure prepare_data:

DELIMITER $$ 
CREATE PROCEDURE prepare_data() 
BEGIN 
    DECLARE i INT DEFAULT 0; 
    TRUNCATE TABLE t1; 
    WHILE i < 1000000 DO 
    INSERT INTO t1 (a, b, c, trt) VALUES ('fasdfadsf', 'asdfasdfa', 'asdfasdf', FLOOR(1 + RAND() *10)); 
    SET i = i + 1; 
    END WHILE; 
END $$ 
DELIMITER ; 
+3

Et moins d'allers-retours entre serveur/client et moins de verrous de table (MyISAM). –

+2

Et le moteur de base de données analysera une requête au lieu de trois. – Benoit

2

SQL Server 2008 R2 Express, ordinateur portable IBM T60p, Core Duo T2500 CPU 2.0GHz, 7200rpm HDD

100000 lignes (pas d'index col2, col1 avec id, col2 avec aléatoire nombre compris entre 0 et 10)

TEST 1: trois requêtes

  1. Insert 100000 Les lignes aléatoires (40 sec)
  2. Requête testée (250 ms)
  3. Tronquer la table
  4. Insérer 100 000 lignes aléatoires. (38 sec)
  5. requête testés (253ms)
  6. truncate table
  7. Insert 100000 Les lignes aléatoires. (39 sec)
  8. requête testés (253ms)
  9. truncate table

TEST 2: seule requête

  1. Insert 100000 Les lignes aléatoires (37 sec)
  2. de requête testés (343ms)
  3. Truncate table
  4. Insérer 100000 aléatoire ws. (39 sec)
  5. requête testés (327ms)
  6. truncate table
  7. Insert 100000 Les lignes aléatoires.(38 sec)
  8. requête (Testée 313ms)

requête utilisée pour les inserts:

truncate table testTable 

    DECLARE @counter int, @col2 int 


    SELECT @counter=0, @col2=RAND(@@spid + cpu + physical_io) 
    FROM master..sysprocesses where [email protected]@spid 

    WHILE (@counter < 1000000) 
     BEGIN 
     SELECT @[email protected] + 10, 
     @col2= CONVERT(int, RAND() * 100) % 10 


     INSERT testTable VALUES (@counter, @col2) 
    END 

requête utilisée pour la mesure:

DECLARE @StartTime datetime,@EndTime datetime 
    SELECT @StartTime=GETDATE() 

    DELETE FROM testTable WHERE col2 = 7; 
    DELETE FROM testTable WHERE col2 = 8; 
    DELETE FROM testTable WHERE col2 = 9; 
    --DELETE FROM testTable where col2 in (7,8,9); 


    SELECT @EndTime=GETDATE() 

    SELECT DATEDIFF(ms,@StartTime,@EndTime) AS [Duration in microseconds] 
+0

Ce n'est pas égal à ce que l'OP a. Il supprime ce qui dans votre cas est col1. Puisque vous n'avez pas d'index sur col2 - vous allez vous retrouver avec des performances de merde. Essayez de le faire à nouveau en utilisant les valeurs col1 comme prédicat. – cairnz

+0

Je ne peux pas attraper si peu de temps ... – Kamil

+0

Kamil, votre test n'est pas lié à une question. La question est pour le moteur de base de données MyISAM, pendant que vous utilisez MS SQL Server. Il y a une énorme différence entre ces deux moteurs de base de données. –

Questions connexes