помогите оптимизировать sql-запрос

Discussion in 'PHP' started by Дикс, 14 Oct 2011.

  1. Дикс

    Дикс Elder - Старейшина

    Joined:
    16 Apr 2006
    Messages:
    1,194
    Likes Received:
    227
    Reputations:
    26
    Здравствуйте, друзья.

    Есть такая задача:

    - имеем список строк (10-30 символов)
    - и имеем таблицу в БД sqlite, такой структуры:
    int uid, string строка, int фейлы

    алгоритм такой:
    - получили строки
    - внесли их в БД, uid по умолчанию null, фейлы - по умолчанию 0
    - обрабатываем строки
    - те строки, с которыми произошла ошибка - обновляются в БД, инкрементируется счетчик фейлов
    - все удачно обработанные строки получают свой уникальный uid, чтобы потом их повторно не обрабатывать

    таблица нужна затем, чтобы запоминать и отсеивать впоследствии те строки, у которых 5 фейлов и больше
    а также те, которые были обработаны ранее (имеют uid)

    проблема у меня на том месте, где мы получили строки и пытаемся из них удалить те, что в базе имеют по 5 фейлов

    я сделал это так:

    PHP:
    select data from rows where data in (перечисляем все строки через запятую) and fails >= or uid is not null
    т.е. достаем строки, которые в (перечисляем все имеющиеся в начале скрипта строки) и без ошибок, либо уже есть uid

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

    1 список строк в запросе порой получается огромным
    2 это неистово жрет память (python3, apache, sqlite3)

    как по вашему будет правильнее удалить из начального списка все строки, имеющие фейлы и имеющие ИД, так чтобы не доставать всю таблицу (она может содержать миллионы строк)?

    можно проверять каждую строку отдельным запросом, но не сожрет ли это все ресурсы?
     
  2. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    Дикс за деревьями - не вижу леса. Вы лучше скажите, что вы хотели организовать в самом начале? Некую очередь заданий для N процессов через бд? Ну так каждый процесс сам знает, какие строки имеют 5+ фейлов, а какие нет, среди тех, которые он получил в самом начале.
     
    _________________________
  3. Дикс

    Дикс Elder - Старейшина

    Joined:
    16 Apr 2006
    Messages:
    1,194
    Likes Received:
    227
    Reputations:
    26
    >>Некую очередь заданий для N процессов через бд?

    ну да, это собственно и есть
    только при каждом запуске потоки пополняют эту очередь
    успешно отработавшие получают уникальный ИД, ошибочные - увеличивают свой счетчик ошибок

    потом запускаем софт повторно, он снова получает извне список новых заданий

    вот цель - убрать из этого списка те задания, что уже помечены в базе как отработавшие
    и убрать те, что есть в базе и имеют 5 ошибок обработки

    >>Ну так каждый процесс сам знает, какие строки имеют 5+ фейлов, а какие нет, среди тех, которые он получил в самом начале.
    он не знает, т.к. это хранится в базе
    он должен получить эти данные

    но при получении он дико сжирает память именно выполнением приведенного выше запроса
     
  4. emmy

    emmy Member

    Joined:
    12 Oct 2009
    Messages:
    76
    Likes Received:
    17
    Reputations:
    8
    вы меня поправьте если чо

    думаю надо начать с этого
    Code:
    select data from rows where data in (...) and [COLOR=Red]([/COLOR]fails >= 5 or uid is not null[COLOR=RED])[/COLOR]  
     
  5. Дикс

    Дикс Elder - Старейшина

    Joined:
    16 Apr 2006
    Messages:
    1,194
    Likes Received:
    227
    Reputations:
    26
    это не может быть причиной жора памяти
    и это работает без скобок, я проверял
     
  6. emmy

    emmy Member

    Joined:
    12 Oct 2009
    Messages:
    76
    Likes Received:
    17
    Reputations:
    8
    вот теперь проблема изолирована. это разные запросы. вы не знаете sql поэтому проверяете их перебором
    сначала нужно изучить sql составить правильныи запрос а затем оптимизировать
     
  7. Дикс

    Дикс Elder - Старейшина

    Joined:
    16 Apr 2006
    Messages:
    1,194
    Likes Received:
    227
    Reputations:
    26
    действительно, and имеет больший приоритет чем or
    спасибо

    пока сделал вариант с доп. временной таблицей, тестирую
    помещаем туда текущий набор строк, выбираем запросом

    select * from _tmp where tid = "временный ИД для строк" and data in (select data from strings where uid is null and fails < 5)
     
    1 person likes this.