SELECT запрос

1. Материалы и компонентная база для исполнения SELECT
Техническая реализация SELECT-запроса в среде Delphi базируется на двух основных наборах компонентов: ADO (TSQLQuery) и FireDAC (TFDQuery). С точки зрения спецификаций, FireDAC использует нативный драйверный слой с прямой компиляцией метаданных, что сокращает время разбора запроса на 18-22% по сравнению с ADO, где применяется OLE DB-прокси. Материалом для выборки служит разметка полей, определённая в свойстве CommandText, которая должна быть строго типизирована для избежания implicit conversion (потери производительности до 40%). Критическим материалом является план выполнения, кешируемый FireDAC в локальной памяти через TFDConnection.Params.Database — это позволяет переиспользовать скомпилированные курсоры без повторного парсинга.
2. Спецификации поведения: курсоры, буферизация и блокировки
SELECT-запрос в Delphi технически различается по режиму курсора. В ADO доступны курсоры adOpenStatic (полная загрузка данных в клиентскую память) и adOpenForwardOnly (потоковая передача). Для FireDAC спецификация FDFetchOptions.Mode задаёт три режима: fmOnDemand (постраничная выгрузка по 50 строк), fmAll (полная буферизация) и fmExact (размер строки фиксирован). Размер буфера по умолчанию — 65000 байт, что критично для запросов с полями BLOB — превышение вызывает многократные round-trips к серверу. Стандарт блокировки: для FireDAC (optimistic) версия записи проверяется только в момент Post, в отличие от ADO, где pessimistic lock удерживается с момента открытия курсора, что повышает конкуренцию на строку в 3-5 раз.
3. Отличия от альтернатив: BDE, dbGo, Unidac — технический анализ
Альтернативные реализации SELECT-запроса: BDE (TQuery) устарел и не поддерживает Unicode, ограничение длины строки — 255 символов в буфере BDE. dbGo (TADOQuery) имеет накладные расходы на маршалинг данных через COM-оболочку — задержка на каждую строку составляет 0.12-0.18 мс против 0.04 мс у FireDAC при размере строки 100 байт. UniDAC использует динамическую подгрузку метаданных, но не поддерживает массивные bulk-операции без внешнего пакета. Ключевое отличие FireDAC от всех альтернатив — встроенный анализатор FDExplainer, который строит план запроса и выявляет index scan без первичного ключа, что позволяет на этапе разработки устранить full table scans.
4. Производство SELECT-запроса: этапы сборки и компиляции
Технический процесс формирования SELECT в Delphi состоит из трёх стадий: 1) Лексический разбор — компонент проверяет синтаксис через парсер, встроенный в TFDCustomQuery. Если запрос содержит %s-подстановки (параметры), FireDAC использует TParsedSQL для генерации параметризованного XML-дерева. 2) Компиляция в нативный код курсора — для FireDAC через TFDDatSManager создаётся внутреннее представление колонок с фиксированным смещением в памяти (offset). 3) Связывание с клиентским буфером — FetchRow заполняет TDataSet.DBRow прямым копированием из сетевого пакета без преобразования типов (raw copy). На этапе производства происходит валидация: если в SELECT указано более 32 колонок, FireDAC автоматически включает FetchOptions.Cache в режим csRecord для снижения накладных расходов на кэш.
5. Стандарты качества исполнения SELECT-запроса
Качество SELECT-запроса в Delphi регламентируется следующими метриками: Latency per row (должна быть не более 0.05 мс для локальной БД и 0.3 мс для сетевой), Rowset size mismatch (не более 2% от размера курсора), Memory fragmentation — использование TFDDatSManager.AllocRecordBuffer не должно превышать 1 MB на 1000 строк. Инструмент FDMonitor фиксирует превышение времени парсинга (норма: менее 10 мс для запроса до 1024 символов). Стандарт кодировки: все SELECT-запросы должны проходить через TFDCommand.Text с параметризацией — прямой конкатенации строк запрещены, так как это в 15 раз увеличивает риск SQL-инъекций по данным OWASP 2026. Для высоконагруженных решений обязательна атрибутизация SELECT ... WITH (NOLOCK) (только для SQL Server) с последующей проверкой через FDExplainer на соответствие уровню изоляции READ UNCOMMITTED.
6. Материалы оптимизации: индексы, типы данных, селективность
Технические материалы, влияющие на скорость SELECT-a: фильтры по индексам — FireDAC автоматически добавляет сортировку по ORDER BY через индекс, если в IndexFieldNames задана колонка, совпадающая с сортировкой. Типы данных — использование WideString (nvarchar) в SELECT увеличивает размер строки на 2 байта на символ, что при потоковой передаче снижает throughput на 12%. Селективность предиката: если WHERE-условие затрагивает менее 5% записей, FireDAC активирует FetchOptions.RecordCountMode в rcmExact, в противном случае — rcmApproximate (быстрее на 30%). Материал TFDLocalSQL позволяет переносить часть фильтрации на клиентскую сторону, что снижает нагрузку на сервер, но требует строгого контроля объёма выбираемых данных: не более 10 000 строк, иначе превышается буферный лимит по умолчанию (256 KB).
7. Рекомендации по сборке SELECT в HighLoad-системах
Для HighLoad-сценариев (более 1000 SELECT-ов в секунду) технические спецификации требуют: использование TFDQuery в связке с TFDDatSManager с отключённым автообновлением метаданных (FetchOptions.AutoClose := True). Категорически запрещён SELECT * — он увеличивает время передачи в 2.7 раза из-за неопределённого порядка колонок. Вместо этого применяется SELECT Col1, Col2 FROM ... с явным списком. Стандарт сборки: все запросы должны быть предварительно откомпилированы через TFDQuery.Prepare — это снижает задержку первого выполнения с 12 мс до 0.3 мс. Для материализации результатов используется FetchRow с размером пачки 100 строк (свойство FetchOptions.RowsetSize), что синхронизировано с размером TCP-сегмента (1460 байт). Качество сборки верифицируется через FDConnection.ExecSQL с замером времени, фиксированным компонентом TFDTimer.
Добавлено: 27.04.2026
