Соединитель MySQL: что быстрее …ГДЕ НЕ СУЩЕСТВУЕТ… или предыдущий выбор?

#mysql #mysql-connector

Вопрос:

Я использую mysql.connector для python, и у меня возникла проблема с подзапросом «где не существует» внутри потока. У меня есть следующий запрос шаблона:

  insert into table
    (a , b, c, cat_id, d)
    SELECT * FROM (SELECT '%s' as a, NOW() as b,
                    2 as c,%s as cat_id,
                    '%s' as d)
                as tmp
    WHERE NOT EXISTS (
        select * from table 
        where 
            cat_id = %s and
            d = '%s'
     ) LIMIT 1;
 

Выполняется в нескольких потоках одновременно с большим количеством разных данных. Но это переполняет мою базу данных, выполнение запросов занимает много времени, и доступ к базе данных становится медленным, ведьма блокирует мои другие запросы.
Мой вопрос: Используя mysql.connector , было бы быстрее сначала попытаться запросить данные ( SELECT * FROM table where cat_id = %s and d = '%s' ), а затем, если он не найдет ни одной строки, попытаться вставить, или это будет еще хуже и займет больше времени?

к твоему сведению, это мой столик:

 table(
   a varchar(30) null,
   b datetime not null,
   c int null,
   cat_id foreigh key,
   d varchar(30)
)
 

сервер mysql: 5.17

python 3.7

Комментарии:

1. %s не должно быть в кавычках.

Ответ №1:

Самый простой способ-добавить уникальный индекс и использовать INSERT IGNORE :

 ALTER TABLE table ADD UNIQUE INDEX (cat_id, d);

INSERT IGNORE INTO table (a, b, c, cat_id, d)
VALUES (%s, NOW(), 2, %s, %s);
 

Кроме того, заполнители не должны быть в кавычках. Вы должны поместить значения во второй аргумент to cursor.execute() , и он будет указывать их по мере необходимости.

Комментарии:

1. Если вы используете printf для заполнения заполнители, вам нужны кавычки, и вы рискуете «внедрением SQL».

2. Я обновил вопрос, чтобы сказать, что они должны использовать cursor.execute() для заполнения параметров, а не .format() .