SQLite3 запрос занимает много времени, как бы вы это сделали? - PullRequest
1 голос
/ 23 марта 2012

У меня есть таблица БД sqlite3 около 250 000 строк, мой код написан на python.Мне нужно отфильтровать его в очень специфические часы, и это занимает слишком много времени.

Таблица выглядит следующим образом:

self.cur.execute("""create table DetectedVehicles(IdD INTEGER PRIMARY KEY, 
                                    CLCode INT, 
                                    DetectionTime INT,
                                    PlateNo VARCHAR)""")

Это таблица для автоматической фильтрации результатов распознавания номеров.И мне нужно отфильтровать его, чтобы получить (нативные SQL-подобные операторы :)):

Get rows from table DetectedVehicles where vehicles were observed at 
CLCode="X" before they were observed at CLCode="Y". 
(implicite: they were observed at both of them)

Поэтому мне нужно получить список обнаруженных транспортных средств, которые пересекли определенные CLCodes в правильной последовательности, т.е.1009 *

Мне удалось создать что-то работающее, но на запрос уходит около 10 секунд.Есть ли более быстрый путь?

Код здесь:

self.cur.execute('select distinct PlateNo from DetectedVehicles where CLCode=? intersect select PlateNo from DetectedVehicles where CLCode=?',(CountLocationNo[0],CountLocationNo[1]))
    PlatesTab=list(self.cur)
    Results=[]
    for Plate in PlatesTab:
        PlateQ1='select * from DetectedVehicles where PlateNo in (?) and ((select DetectionTime from DetectedVehicles where CLCode = ? and PlateNo in (?) ) <  (select DetectionTime from DetectedVehicles where CLCode = ? and PlateNo in (?)))'     
        R=list(self.cur.execute(PlateQ1,(Plate,CountLocationNo[0],Plate,CountLocationNo[1],Plate)))
        if R:
            TimesOD=self.curST2.execute('select DetectionTime from DetectedVehicles where PlateNo in (?) and (CLCode= ? or CLCode=?)',(Plate,CountLocationNo[0],CountLocationNo[1])).fetchall()
            if TimesOD:
               TravelTimes.append(TimesOD[1][0]-TimesOD[0][0])
               DetectionTimes.append(TimesOD[0][0])
            for i in R:
                Results.append(i[0])
    Results=tuple(Results)
    QueryCL=' intersect select * from DetectedVehicles where IDd in ' + str(Results)

Заранее спасибо

Ответы [ 3 ]

2 голосов
/ 23 марта 2012

Вы можете сделать все это в одном запросе.

select 
    dv1.PlateNo, dvPoint1.DetectionTime, dvPoint2.DetectionTime
from 
    DetectedVehicles dvPoint1 
    inner join DetectedVehicles dvPoint2
        on dvPoint1.PlateNo = dvPoint2.PlateNo
        and dvPoint1.CLCode = ? and dvPoint2.CLCode = ?
        and dvPoint1.DetectionTime < dvPoint2.DetectionTime

Вам понадобится индекс для (PlateNo, DetectionTime, CLCode) или (CLCode, PlateNo).Попробуйте оба, чтобы увидеть, что быстрее.PlateNo по себе может сделать.

1 голос
/ 23 марта 2012

Попробуйте:

select distinct x.*
from DetectedVehicles x
join DetectedVehicles y
  on x.PlateNo = y.PlateNo and 
     x.DetectionTime < y.DetectionTime
where x.CLCode=? and y.CLCode=?

или

select x.*
from DetectedVehicles x
where exists
(select 1
 from DetectedVehicles y
 where x.PlateNo = y.PlateNo and 
       x.DetectionTime < y.DetectionTime and
       x.CLCode=? and y.CLCode=?)

Обычно я ожидаю, что последний запрос будет выполняться быстрее, но стоило бы выполнить оба для проверки.

0 голосов
/ 23 марта 2012

Спасибо, ребята, за этот отзыв. Я отправляю это как ответ, и результаты настоящего времени:

1. самый быстрый результат (запрос 1,80 с, выборка 0,20 с, всего 2 с)

select distinct x.*
from DetectedVehicles x
join DetectedVehicles y
  on x.PlateNo = y.PlateNo and 
     x.DetectionTime < y.DetectionTime
where x.CLCode=? and y.CLCode=?

2. (запрос 1,83 с, выборка 0,19 с, всего 2,02 с)

select 
    dvPoint1.PlateNo, dvPoint1.DetectionTime, dvPoint2.DetectionTime
from 
    DetectedVehicles dvPoint1 
    inner join DetectedVehicles dvPoint2
        on dvPoint1.PlateNo = dvPoint2.PlateNo
        and dvPoint1.CLCode = ? and dvPoint2.CLCode = ?
        and dvPoint1.DetectionTime < dvPoint2.DetectionTime

3. (запрос 1,82 с, выборка 1,09 с, всего 2,91 с)

select x.*
from DetectedVehicles x
where exists
(select 1
 from DetectedVehicles y
 where x.PlateNo = y.PlateNo and 
       x.DetectionTime < y.DetectionTime and
       x.CLCode=? and y.CLCode=?)

Так что, спасибо @Mark Bannister за Ваш ответ, я приму его.

Однако остается одна проблема: cur.fetchall () занимает чрезвычайно много времени .. и мне нужно получить результаты, как мне это сделать? (Всего для 100 строк это занимает около 2 минут для каждого из ваших решений). Решенная проблема: загрузите новый sqlite.dll в вашу папку python / dlls ... не спрашивайте меня, почему: Присоединиться с помощью Pylons sqlite модуль медленнее, чем делать это вручную

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...