Гигантская тормозная база, секционирование и ускорение
От: Слава  
Дата: 18.01.23 02:03
Оценка: 1 (1)
Есть база MS SQL на полтора терабайта, а может и больше, я не видел сам прод.

В ней имеется 9 миллионов клиентов, у которых имеются сотни тысяч транзакций (в бизнес-смысле). Это данные о проезде автомобилей через ворота, условно говоря.

Всякие гриды в тормозном веб-интерфейсе тормозят ещё сильнее во время выборки. А выборка в типовой хранимке происходит так: заполняем временную таблицу уймой запросов по всем данным заданного клиента, затем фильтруем временную таблицу по значениям фильтра из грида, по всем 50 колонкам, по всему миллиону строк, вот в таком духе:

                AND (
                    (@ipv_biTransactionID IS NULL AND @ipv_vcTransactionOperator IS NULL)
                    OR (@ipv_vcTransactionOperator = 's%' AND Y.CustTrxnID LIKE (CAST(@ipv_biTransactionID AS VARCHAR(MAX)) + '%'))
                    OR (@ipv_vcTransactionOperator = 'e%' AND Y.CustTrxnID LIKE ('%' + CAST(@ipv_biTransactionID AS VARCHAR(MAX))))
                    OR (@ipv_vcTransactionOperator = '=' AND Y.CustTrxnID = @ipv_biTransactionID)
                    OR (@ipv_vcTransactionOperator = '!=' AND Y.CustTrxnID != @ipv_biTransactionID)
                    OR (@ipv_vcTransactionOperator = 'IN' AND Y.CustTrxnID LIKE ('%' + CAST(@ipv_biTransactionID AS VARCHAR(MAX)) + '%'))
                    OR (@ipv_vcTransactionOperator = 'NOT IN' AND Y.CustTrxnID NOT LIKE ('%' + CAST(@ipv_biTransactionID AS VARCHAR(MAX)) + '%'))
                )            
                AND (
                    (@ipv_iTrxnStatus IS NULL AND @ipv_vcTrxnStatusOperator IS NULL)
                    OR (@ipv_vcTrxnStatusOperator = 's%' AND Y.TrxnStatusID LIKE (CAST(@ipv_iTrxnStatus AS VARCHAR(MAX)) + '%'))
                    OR (@ipv_vcTrxnStatusOperator = 'e%' AND Y.TrxnStatusID LIKE ('%' + CAST(@ipv_iTrxnStatus AS VARCHAR(MAX))))
                    OR (@ipv_vcTrxnStatusOperator = '=' AND Y.TrxnStatusID = @ipv_iTrxnStatus)
                    OR (@ipv_vcTrxnStatusOperator = '!=' AND Y.TrxnStatusID != @ipv_iTrxnStatus)
                    OR (@ipv_vcTrxnStatusOperator = 'IN' AND Y.TrxnStatusID LIKE ('%' + CAST(@ipv_iTrxnStatus AS VARCHAR(MAX)) + '%'))
                    OR (@ipv_vcTrxnStatusOperator = 'NOT IN' AND Y.TrxnStatusID NOT LIKE ('%' + CAST(@ipv_iTrxnStatus AS VARCHAR(MAX)) + '%'))
                )        
            WHERE x.RowNumber BETWEEN @v_iStartIndex AND @v_iEndIndex
            ORDER BY x.RowNumber;



Транзакции могут быть переданы между клиентами, но чаще всего они происходят в рамках одного клиента. Исторические данные никак от текущих не отделены, в базе есть и 2005 год.

Как бы эту базу распилить, чтобы не тормозила? Если у большей части самых гигантских таблиц есть accountId, то логично было бы применить секционирование по этому id. Но 9 миллионов секций не поддерживаются MS SQL, это слишком много.

Секционирование можно сделать например по 2 последним цифрам в id клиента. Хорошая ли это идея? Что вообще с такой базой можно сделать?
Отредактировано 18.01.2023 2:19 Слава . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.