Прям озадачили. Самая производительная стратегия это делать запросы только по индексам, и уменьшать "жадность" запроса.
Вторая это денормализация данных.
Третья использование prepared statement
Четвертая логика на стороне БД !!!!!!! очень опасная штука!!!!!!!!!!
Иван Мельников, Все это можно сделать в приложении, кроме того там вы получите большую гибкость и контроль за исполнением кода, и IDE не даст выстрелить в ногу.
tsql, plsql слишком низкоуровневые. Применять их стоит крайне осторожно и только в случаях когда именно это место "узкое" и вы точно знаете что проблема именно тут. То есть вы получили отчет и видите что нужно больше скорости.
Иван Мельников,
Преждевременная оптимизация — корень всех зол. — статья «Structured Programming with go to Statements» в сборнике «Computing Surveys» (Vol. ... Premature optimization is the root of all evil. Преждевременная оптимизация — корень всех (или большинства) проблем в программировании.
Нет производительности как таковой, есть производительность в данном конкретном сценарии. Если она вас не устраивает, вы начинаете оптимизировать. А так пишите понятный код, возможно и не самый быстрый, потом исправите ну или нет если будет работать правильно.
Я правильно понимаю, что вы педалируете подход, при котором на каждый чих придется вываливать из базы некоторое количество десятков мегабайт данных (нам же страшно писать хранимые процедуры, это сложна), обрабатывать их в приложении (под контролем IDE, а не схемы данных), а потом, возможно, лить обратно.
Большая гибкость, под названием "бэкэнд опять навалили хрени, которую DBA вынужден разгребать?"
Контроль за исполнением кода невозможен на стороне СУБД? Что за сказка? Вам отключили отладчик plsql за неуплату?
Ваши подходы работают до тех пор, пока структура данных может уместиться в голове у одного разработчика без влезания в документацию. Как только зависимостей и нюансов станет слишком много, придется переизобретать схему данных на стороне приложения (ура, мы напишем свой SQL, с блекждеком!).
Армянское Радио, Мы сейчас за суровый энтерпрайз или за веб?
И что это вы предлагаете в количестве десятков мегабайт таскать?
Я например имел в виду CRED операции по простому списку.
Например вот апи для получения статей, по вкусу можно прикрутить лимиты, сортировку и прочее.
В базе тоже не особо сложно, разве что метаполя для документа в json.
Хотя для бизнеса бывает нужно что то посложнее, но реально, там черт ногу сломит.
То есть вы предлагаете что то типа такого?
/****** Object: StoredProcedure [dbo].[Akkum_Year] Script Date: 25.11.2019 9:55:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ================================== ----- =======================================================
ALTER PROCEDURE [dbo].[Akkum_Year]
@KindProvisionCorpCode int
AS
Begin
Declare
@RowNum int,
@LicProvisionID int,
@Value_Year decimal(15,4),
@ObjCorpCode int,
@Year int,
@Year_dt datetime,
@Format int
set Language russian -- для правильного формата даты
-- Выбрать из LicProvisionValue все даты, соотв. фактической добыче нефти
-- по месяцам
Declare Cur_F cursor for
SELECT
lv.LicProvisionID,
SUM(lv.Value) AS Value_Year,
YEAR(lv.DateStart) AS Year,
lv.ObjCorpCode
FROM dbo.LicProvision lp INNER JOIN
dbo.LicProvisionValue lv ON lp.LicProvisionID = lv.LicProvisionID
GROUP BY lp.KindProvisionCorpCode,
(lv.DateStart),
lp.EntityID,
lv.ObjCorpCode,
lv.LicProvisionID,
lv.SourceProvisionCorpCode,
lv.DateStartFmt
HAVING (lp.KindProvisionCorpCode = @KindProvisionCorpCode)
AND (lv.SourceProvisionCorpCode = 2309453)
AND (lv.DateStartFmt = 2187799)
OPEN Cur_F
FETCH NEXT FROM Cur_F
INTO
@LicProvisionID,
@Value_Year,
@Year,
@ObjCorpCode
SET @RowNum = 0
WHILE @@FETCH_STATUS = 0
BEGIN
set @RowNum = @RowNum + 1
print cast(@RowNum as char(8)) + ' ' + cast( @Year as char(4))
+ ' '+ cast(@Value_Year as char(15))
set @Year_dt =Convert(datetime, '31.12.' + cast( @Year as char(4)))
IF NOT EXISTS(SELECT LicProvisionValueID From LicProvisionValue
Where LicProvisionID = @LicProvisionID
AND YEAR(DateStart) = @Year
AND DateStartFmt = 2187801
AND SourceProvisionCorpCode = 2309453)
BEGIN
INSERT INTO LicProvisionValue
(LicProvisionID,
ObjCorpCode,
SourceProvisionCorpCode,
DateStartFmt,
DateStart,
DateEndFmt,
DateEnd,
Value,
DynamicFlag,
AutoFlag
)
VALUES
(
@LicProvisionID,
@ObjCorpCode,
2309453, --факт
2187801, --год
@Year_dt,
2187801, --год
@Year_dt,
@Value_Year,
1,
1
)
END
FETCH NEXT FROM Cur_F
INTO
@LicProvisionID,
@Value_Year,
@Year,
@ObjCorpCode
END
CLOSE Cur_F
DEALLOCATE Cur_F
end -- конец процедуры
--
Владимир Коротенко, да, я предлагаю что-то вот такое. Можно заметить, что большая часть кода тут - это перечисление полей, а не логика.
Граница проходит не в "суровости" энтерпрайза, а в критичности порчи данных. Логика, сидящая в СУБД просто не позволит нарушить консистентность данных. Если же логика частично там, частично там - все держится на сознательности кожаных мешков, которые пишут код. А кожаные мешки, увы, ляпают ошибки чаще, чем это делает движок СУБД.
Насколько я в курсе, транзакции уже завезли во все нормальные языки программирования.
И это там удобней реализовано. А для БД стоит оставить его главную задачу отдавать запросы и контролировать целостность данных, без проверок в коде, только ключами.
100% есть. Например, не стоит делать джоин на стороне клиента, выбрав из одной таблицы, и потом в цикле выбирая из второй (даже если на второй таблице выборка идет по индексу). Лучше отправить один запрос РСУБД.