Проверить, какие идентификаторы существуют postgrestable

Что такое быстрая проверка того, какие идентификаторы существуют в таблице postgreSQL

Я написал следующую функцию, но она работает очень медленно, когда len(x) больше 500 000

import psycopg2
conn = psycopg2.connect(...)
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

def check_exist(lst):
    exist = []
    not_exist = []
    for i in lst:
        cursor.execute(f"SELECT * FROM table1 where id = {i}")
        row = cursor.fetchone()
        if row:
            exist.append(i)
        else:
            not_exist.append(i)
    return exist, not_exist

x, y = check_exist(['2','4','3000','50000','10000000'])

Почему вы вообще проверяете, существует ли идентификатор в базе данных из Python?

Chris 11.12.2020 01:25

В любом случае, да, вы делаете 500 000 SELECT * запросов для 500 000 идентификаторов. Это будет медленно. Это почти наверняка проблема XY. Если вы объясните, чего вы пытаетесь достичь, мы, вероятно, сможем порекомендовать лучший подход.

Chris 11.12.2020 01:25

@Chris Я пишу скрипт, который должен создать 2 таблицы на основе пользовательского ввода, пользовательский ввод в моей модели даст мне список идентификаторов (в идеале пользователь выберет максимум 10000 идентификаторов), но я хочу сделать это быстрее, поэтому я ищу лучшие способы сделать это

goku 11.12.2020 01:29

«пользовательский ввод в моей модели даст мне список идентификаторов» — почему? Что вы хотите делать с этими идентификаторами?

Chris 11.12.2020 01:30

@Chris Возможно, мне следовало упомянуть, что это для приложения Django, где пользователь отправляет форму (выбирает элементы), при отправке создается список идентификаторов, идентификаторы необходимо проверить, если они существуют в таблице -> если да, то товар есть в наличии, иначе его нет в наличии, наконец, товары, выбранные пользователем, будут отображаться на 2 разных веб-страницах.

goku 11.12.2020 01:39

...У меня так много вопросов по этому поводу. Откуда в первую очередь берутся идентификаторы? Пользователи вводят числа? Поиск вещей? Зачем кому-то отправлять от 10 до 500 тысяч элементов в одной форме? Почему «в наличии» означает «идентификатор существует»? Разве наличие удостоверения личности и наличие на складе не должны быть разными вещами? У вас определенно, определенно проблема XY, как я уже говорил ранее. Пожалуйста, уменьшите масштаб и переосмыслите то, чего вы пытаетесь достичь. Если вы объясните, что мы могли бы помочь, но это также может быть слишком широким для SO.

Chris 11.12.2020 01:43
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
6
322
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать предложение IN. Создайте список с вашими идентификаторами. Повторите список в своем приложении, чтобы проверить, какие идентификаторы не фигурируют в списке найденных записей.

Выберите идентификатор из таблицы 1, где идентификатор IN ([ваш список])

Суть: запрос меньшего количества полей из таблицы делает ваш запрос более эффективным.

Предложение IN с 500 000 записей, вероятно, тоже не лучшая идея. У OP проблема XY, и нам нужно больше узнать о том, что они пытаются сделать, прежде чем мы сможем дать хороший совет.

Chris 11.12.2020 01:28

Мне все равно, что находится в строке в данный момент, я просто проверяю, существует ли идентификатор или нет. Я буду использовать идентификатор в более поздней функции

goku 11.12.2020 01:41
Ответ принят как подходящий

Вы можете использовать ANY и позволить Postgres сделать большую часть работы:

import psycopg2, time
# database is in a datacenter just using a tunnel!
conn = psycopg2.connect("dbname=mf port=5959 host=localhost user=mf_usr")
cur = conn.cursor()

ids = [x for x in range(0, 750000)]

sql = """
    SELECT array_agg(id) from __users where id = ANY(%s);
"""
# array_agg: Postgres returns an array of ids!

_start = time.time()
cur.execute(sql, (ids, ))
existingIds = cur.fetchone()[0]
missingIds = set(ids) - set(existingIds)

print(len(existingIds))
print(len(missingIds))
print('Took: %.6f seconds' % (time.time() - _start))

Вне:

284365
465635
Took: 5.564851 seconds

Примечание. Убедитесь, что у столбца идентификатора есть индекс.

именно то, что я просил, кстати, вы можете использовать ids = list(range(750000))

goku 11.12.2020 02:08

Я все еще думаю, что это была проблема XY, но я думаю, вы ответили на вопрос ОП.

Chris 11.12.2020 02:09

@goku: я всегда забываю об этом :)

Maurice Meyer 11.12.2020 02:17

Другие вопросы по теме