У меня есть таблица INVESTOR_OPPORTUNITY, которая структурирована следующим образом:
- ID // PRIMARY KEY
- INVESTOR_ID
- OPPORTUNITY_ID
- POINTS // values 0 to 5
ИНВЕСТОР может быть связан с одной и той же возможностью несколько раз, и на каждую возможность обычно приходится 10000 инвесторов. Таким образом, в среднем на каждую возможность приходится около 20 000 строк.
В моем GridView мне нужно отобразить по одной строке на каждого инвестора с количеством набранных возможностей 1, 2, 3, 4, 5. Примерно так:
INVESTOR_ID | count of 1pt | count of 2pt | etc
123456 | 7 | 13 | etc
Вотосновная часть запроса:
->select([
'INVESTOR_ID',
'SUM( CASE WHEN OPP.POINTS=0 THEN 1 ELSE 0 END) AS countPoints0',
'SUM( CASE WHEN OPP.POINTS=1 THEN 1 ELSE 0 END) AS countPoints1',
'SUM( CASE WHEN OPP.POINTS=2 THEN 1 ELSE 0 END) AS countPoints2',
'SUM( CASE WHEN OPP.POINTS=3 THEN 1 ELSE 0 END) AS countPoints3',
'SUM( CASE WHEN OPP.POINTS=4 THEN 1 ELSE 0 END) AS countPoints4',
'SUM( CASE WHEN OPP.POINTS=5 THEN 1 ELSE 0 END) AS countPoints5',
])
->andWhere([OPPORTUNITY_ID=>$this->OPPORTUNITY_ID])
->groupBy(['INVESTOR_ID']);
Это работает нормально и довольно быстро. Однако, как только я отфильтрую значение в одном из показателей, запрос может занять более 17 секунд, а иногда и больше, чем одну или две минуты!
Например: если я хочу увидеть всех инвесторов, которые имеют более 1 возможности с нулевыми точками:
->select([
'INVESTOR_ID',
'SUM( CASE WHEN OPP.POINTS=0 THEN 1 ELSE 0 END) AS countPoints0',
'SUM( CASE WHEN OPP.POINTS=1 THEN 1 ELSE 0 END) AS countPoints1',
'SUM( CASE WHEN OPP.POINTS=2 THEN 1 ELSE 0 END) AS countPoints2',
'SUM( CASE WHEN OPP.POINTS=3 THEN 1 ELSE 0 END) AS countPoints3',
'SUM( CASE WHEN OPP.POINTS=4 THEN 1 ELSE 0 END) AS countPoints4',
'SUM( CASE WHEN OPP.POINTS=5 THEN 1 ELSE 0 END) AS countPoints5',
])
->having('SUM( CASE WHEN OPP.POINTS=0 THEN 1 ELSE 0 END) >1')
->andWhere([OPPORTUNITY_ID=>$this->OPPORTUNITY_ID])
->groupBy(['INVESTOR_ID']);
Я попробовал комбинацию индексов (INVESTOR_ID: OPPORTUNITY_ID: POINTS), ноне повезло.
Как я могу оптимизировать этот запрос ??
Любая помощь приветствуется.