MySQL оператор "IN", чтобы удалить несколько строк или несколько запросов?Что быстрее? - PullRequest
1 голос
/ 20 февраля 2012

Я использую MySQL.Движок таблиц - MyIsam

Какой метод быстрее?

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

или

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

Поле id - это ПЕРВИЧНЫЙ КЛЮЧ

Какой из них будет работать быстрее?

Ответы [ 2 ]

5 голосов
/ 20 февраля 2012

IN должно быть быстрее, потому что mysql будет обновлять ваши индексы и перемещать блоки данных после каждого запроса в вашем втором решении, в то время как это произойдет только один раз с первым запросом.

А вот некоторые тесты на MySQL(для таблицы, имеющей один столбец int и 3 varchars, заполненных случайными данными и по индексу для столбца в WHERE ... без индекса нет смысла, поскольку в обоих случаях это занимает намного больше времени ... но все жеLooot медленнее с 3 запросами, чем 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> 

Таким образом, эти три запроса заняли намного больше времени - 7,39 с против 5,25 с для IN, что на 40% больше).Вот процедура 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 ;
2 голосов
/ 20 февраля 2012

SQL Server 2008 R2 Express, ноутбук IBM t60p, процессор Core Duo T2500 с частотой 2,0 ГГц, жесткий диск 7200 об / мин

100000 строк (без индекса для col2, col1 с идентификатором, col2 со случайным числом от 0 до 10)

ТЕСТ 1: три запроса

  1. Вставка 100000 случайных строк (40 секунд)
  2. Протестированный запрос (250 мс)
  3. Усеченная таблица
  4. Вставка 100000 случайных строк.(38 секунд)
  5. Протестированный запрос (253 мс)
  6. Усеченная таблица
  7. Вставка 100000 случайных строк.(39 секунд)
  8. Протестированный запрос (253 мс)
  9. Усеченная таблица

ТЕСТ 2: один запрос

  1. Вставить 100000 случайных строк (37 секунд)
  2. Протестированный запрос (343 мс)
  3. Таблица усечений
  4. Вставить 100000 случайных строк.(39 секунд)
  5. Протестированный запрос (327 мс)
  6. Усеченная таблица
  7. Вставка 100000 случайных строк.(38 секунд)
  8. Протестированный запрос (313 мс)

Запрос, используемый для вставок:

    truncate table testTable

    DECLARE @counter int, @col2 int


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

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


        INSERT testTable VALUES (@counter, @col2)
    END

Запрос, используемый для меры:

    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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...