JohnyDeath писал(а) 31. Октября 2007 :: 15:14:Я может что пропустил...
Такой запрос:
SELECT
Агенты.descr as ИмяАгента,
Sum(РегОстатки.Количество) as Кол
FROM Регистр_БСО as РегОстатки
left join Справочник_Сотрудники as Агенты on РегОстатки.Лицо = Агенты.id
WHERE
РегОстатки.Date between '20050101' and '20050131'
Group by ИмяАгента
отрабатывает за 913 мс
меняем left на inner и получаем время выполнения: 33519
в случае с лэфтом вот такой план:
0 0 TABLE Регистр_БСО AS РегОстатки VIRTUAL TABLE INDEX 1:RA25709.DATETIME;? 0;
0;
1 1 TABLE Справочник_Сотрудники AS Агенты VIRTUAL TABLE INDEX 0:SC208.IDD;?
0;с иннером:
0 1 TABLE Справочник_Сотрудники AS Агенты VIRTUAL TABLE INDEX 4:SC208.DESCR;> ORDER BY
1 0 TABLE Регистр_БСО AS РегОстатки VIRTUAL TABLE INDEX 1:RA25709.DATETIME;? 0;
0;Т.е в случае с "иннер" неправильно выбирается индекс? Я правильно понял?
Именно.
Когда применяется left join, порядок таблиц во from изменять нельзя. Поэтому SQLite вынужден идти по регистру по индексу DATETIME, подтягивать к нему записи из справочника, группируя затем их самостоятельно.
В случае же с inner join таблицы можно поменять местами, и SQLite предпочитает в данном случае пойти сначала по справочнику по индексу DESCR, полагая, что это облегчит ему дальнейшую группировку.
Каюсь, в этом по большей части моя вина, так как о цене использования индексов по таблицам 1С я информирую SQLite пока крайне приблизительно.
Пока же можно для правильного выбора индекса применить трюк с "+" :
SELECT
Агенты.descr as ИмяАгента,
Sum(РегОстатки.Количество) as Кол
FROM Регистр_БСО as РегОстатки
inner join Справочник_Сотрудники as Агенты on РегОстатки.Лицо = Агенты.id
WHERE
РегОстатки.Date between '20050101' and '20050131'
Group by +ИмяАгента
+ перед колонкой ничего не делает, но исключает ее из кандитатов на использование индексов.