1С:Предприятие
:: 1С:Предприятие 7.7 и ранее
|
|
| ||
Volodja 21.01.21 - 14:52 | В чем может быть причина? Не пойму.
тз=СоздатьОбъект("ТаблицаЗначений"); ТаблицаЗамен.Выгрузить(тз,,,"СтароеЗначение"); тз.НоваяКолонка("ИИН","Строка",12); тз.ВыбратьСтроки(); Пока тз.ПолучитьСтроку()=1 Цикл _Элемент=тз.СтароеЗначение; тз.ИИН=_Элемент.ИИН; КонецЦикла; глБД_SQLite.УложитьТЗ(тз,"тзЗамены"); ТекстЗапроса = " |SELECT | Substr(тзЗамены.СтароеЗначение,7,9) as [СтарыйЭлемент :Справочник.Клиенты], | СпрК.ID as [НовыйЭлемент :Справочник.Клиенты] |FROM | тзЗамены | INNER JOIN [Справочник.Клиенты] as СпрК | ON (тзЗамены.ИИН = СпрК.ИИН) AND | (Trim(СпрК.ИИН)<>'') | |"; ТекстЗапроса = " |SELECT | Substr(тзЗамены.СтароеЗначение,7,9) as [СтарыйЭлемент :Справочник.Клиенты], | СпрК.ID as [НовыйЭлемент :Справочник.Клиенты] |FROM | [Справочник.Клиенты] as СпрК | INNER JOIN тзЗамены | ON (тзЗамены.ИИН = СпрК.ИИН) AND | (Trim(СпрК.ИИН)<>'') AND | (СпрК.ismark <> '*') | |"; В справочнике около 100 000 записей в тз около 200-300 Отладочная информация Подбор индекса для таблицы SC14 : Ограничения: ISMARK ne; SP968[ИИН]=; Выбран индекс VI968: UPPER(SP968) Стоимость: 16 Подбор индекса для таблицы SC14 : Ограничения: ISMARK ne; Индекс не выбран. Стоимость: 74318 | ||
ДенисЧ 1 - 21.01.21 - 14:54 | AND Trim(СпрК.ИИН)<>'') Забудь про индексы, скажи "превед" перебору таблицы | ||
Volodja 2 - 21.01.21 - 14:56 | <> - Не использовать? | ||
ДенисЧ 3 - 21.01.21 - 14:56 | (2) Для начала Trim() )))
Это же функция, чтобы её посчитать - нужно получить каждую строку таблицы... | ||
Volodja 4 - 21.01.21 - 14:57 | Как тут тогда отсечь пустые? | ||
youalex 5 - 21.01.21 - 15:00 | а в склайте разве '' <> ' '?
или у тебя там не только пробелы могут быть ? | ||
Volodja 6 - 21.01.21 - 15:02 | (5) этим я игнорирую пустые ИИН | ||
Volodja 7 - 21.01.21 - 15:02 | ИИН это 12-значная строка из цифр | ||
Volodja 8 - 21.01.21 - 15:04 | |||
Volodja 9 - 21.01.21 - 15:05 | Индекс по ИИН есть | ||
youalex 10 - 21.01.21 - 15:10 | А зачем тебе вообще это условие, у тебя же INNER JOIN тзЗамены.ИИН = СпрК.ИИНт.е. ты можешь сначала в ТЗ отобрать элементы без пустого ИНН? | ||
Volodja 11 - 21.01.21 - 15:15 | (10) Могу, конечно. Но почему это так долго работает? | ||
Ёпрст 12 - 21.01.21 - 15:16 | (11) скан всей таблички жешь | ||
Volodja 13 - 21.01.21 - 15:57 | Сделал по совету (10). Отобрал предварительно все непустые ИИН.Заработало как надо.Быстро.
Получается сканирование таблицы сильно зависит от размера строки? Это условие ведь осталось. хотя индекса нет
СпрК.ismark <> '*'
А в этом
(СпрК.ИИН<>' ')
ИИН = 12 символов и тормозит уже жутко | ||
Sserj 14 - 21.01.21 - 15:59 | (11) На сколько помню Djelf писал что SQLite вообще ничего не знает об индексах 1С. То что в отладке говорится "подобрн" это уже вроде как сам движок 1С сообщает. А SQLite без информации об индексах план придумывает "от балды", в частности у тебя вот решил сначала выбрать все не помеченные на удаление а потом уже связать по ИНН.
Помнится в таких случаях частенько приходилось разбивать на подзапросы, чтобы нужный индекс задействовать. Что-то типа такого: ТекстЗапроса = "
|SELECT [СтарыйЭлемент :Справочник.Клиенты], [НовыйЭлемент :Справочник.Клиенты]
|FROM (
|SELECT
| Substr(тзЗамены.СтароеЗначение,7,9) as [СтарыйЭлемент :Справочник.Клиенты],
| СпрК.ID as [НовыйЭлемент :Справочник.Клиенты],
| Trim(СпрК.ismark) as [ПометкаУдаления]
|FROM
| [Справочник.Клиенты] as СпрК
| INNER JOIN тзЗамены
| ON (тзЗамены.ИИН = СпрК.ИИН) AND
| (Trim(СпрК.ИИН)<>'')
|) as T
|WHERE NOT T.ПометкаУдаления = '*'
|
|"; | ||
Volodja 15 - 21.01.21 - 16:09 | Ок.Спасибо всем. Буду теперь аккуратнее со строками. | ||
Djelf 16 - 21.01.21 - 16:44 | (14) Не совсем так. Про индексы движок то знает, но статистики индексов нет, и в случае с INNER JOIN может ошибиться в плане запроса и поменять выборку из таблиц местами.
С LEFT JOIN такой проблемы нет, выборка из таблиц местами не меняется. Все становится более предсказуемо. Нужно смотреть план запроса через "explain QUERY PLAN "+ТекстЗапроса и более детально через "explain QUERY PLAN "+ТекстЗапроса. В данном запросе "ON (тзЗамены.ИИН = СпрК.ИИН) AND (Trim(СпрК.ИИН)<>'')" видимо должно быть 2 сканирования таблицы СпрК. Первое по индексу, второе - сырым чтением, потому что Trim(СпрК.ИИН) заблокирует выборку по индексу, потому что идет вычисление перед сравнением! А "сырое" чтение иногда оказывается быстрее, например: SELECT count(*) FROM Справочник_Контрагенты WHERE РольПокупатель=1// по индексу будет на 10% медленнее SELECT count(*) FROM Справочник_Контрагенты WHERE +РольПокупатель=1// а вот тут РольПокупатель модифицируется и индекс идет в ближайший лес... |
|
Список тем форума |