У меня есть гибридный запрос, который вызывает очень большое sql представление сервера, которым пользователи могут манипулировать. Одно из полей - это битовый флаг с именем status
. Теперь, если бы я должен был проверить, что флаг установлен в какой-то определенный c флаг, который работает, и запрос свернут, и предикат переводится в sql. Так, например, если я просто хочу проверить, установлен ли флаг 16, это работает
let
source = Sql.Database("some_server", "db"),
query = source{[Schema="dbo",Item="v_big_view"]}[Data]
filter = Table.SelectRows(query,each [status]=16)
in
filter
Это работает нормально и генерирует sql, вы ожидаете что-то похожее на: *
select [t].[col1],[t].[col2],...,[t].[status]
from [dbo].[v_big_view] as [t]
where [t].[status]=16
Но я упускаю все, что находится в состоянии 16 и других состояниях (например, если статус равен 31). Если я переключу фильтр на each Number.BitwiseAnd([status],16)<>0
, запрос вместо этого изменится на
select [t].[col1],[t].[col2],...,[t].[status]
from [dbo].[v_big_view] as [t]
, и power bi обрабатывает фильтр в памяти, что является медленным и очень дорогостоящим из-за большого представления.
В качестве решения для бедняка я создал fn, который делает это:
create function dbo.fn_big_view(@mask int)
returns table
with schemabinding as return
select [t].[col1],[t].[col2],...,[t].[status]
from [dbo].[v_big_view] [t]
where [t].[status]&@mask<>0
И это работает, но проблематично c, как будто пользователь не заинтересован в фильтрации по маске, они все еще платят за тестирование. (даже если они используют @mask=-1
).
Есть ли другой способ сделать это?