Querying sys-tables, for instance sys.columns, sys.indexes or sys.tables, has become significantly slower on SQL Server 2022 on Linux for users which are not db_owner.
To reproduce, take a SQL Server 2022 on Linux (I've used 16.0.4035 which is the latest version as of this writing) and execute the following commands. It creates a dummy database with 500 tables with 10 columns each, such that sys.columns for this database gets about 5000 records. You can skip creating the dummy database if you have a database with a total of >1000 columns at hand.
CREATE DATABASE SLOWSYSTABLES
GO
USE SLOWSYSTABLES
DECLARE @i int
DECLARE @createTable nvarchar(max)
SET @i = 0
WHILE (@i < 500)
BEGIN
SET @createTable = 'CREATE TABLE dummy_' + CAST(@i as nvarchar) + '(Col1 int not null identity(1,1) primary key, Col2 int, Col3 int, Col4 int, Col5 int, Col6 int, Col7 int, Col8 int, Col9 int, Col10 int)'
SET @i = @i + 1
exec sp_executesql @createTable
END
CREATE LOGIN slowsystables_reader WITH password='Asdfasdf1', check_policy=off
CREATE USER slowsystables_reader FOR LOGIN slowsystables_reader
ALTER ROLE db_datareader ADD MEMBER slowsystables_reader
Now, I execute the following query:
SET STATISTICS TIME on
USE SLOWSYSTABLES
SELECT * FROM sys.columns
On my system (Intel i7-10700k, 32GB RAM, M.2 SSD disk), the execution time as sa or any user with db_owner permissions is about 100ms. But if slowsystables_reader runs the query, the execution time is 13 seconds. SQL Server uses 100% of the available CPUs for the entire 13 seconds.
(5048 rows affected)
SQL Server Execution Times:
CPU time = 7138 ms, elapsed time = 13194 ms.
The issue disappears if slowsystables_reader is added to the db_owner database role and immediately reappears if the user is removed from the role again.
This issue is not present in SQL Server 2019 on Linux or 2019/2022 on Windows.
I can reproduce this on a freshly installed SQL Server 2022 on a freshly installed Ubuntu 20.04 Server or Debian bullseye. I also tried it on two different systems (both VMs, one Hypver-V, one KVM backed, but with different underlying hardware). The sole queries the SQL Server has ever executed are the ones above.
I tried updating system table stats, but no cigar.
Unfortunately, I don't have a Microsoft Support Plan and hence cannot open a support case with Microsoft.
I saw in my execution plan that SQL Server is spending nearly 100% of its time on the has_access function, and AFAIK it's "known" that has_access is short-circuited if the user is db_owner. So this is the same root case as Query against sys.schemas and sys.synonyms runs very slow for one user, but AFAIK I have absolutely no influence on has_access and I can't really rewrite/optimize SELECT * FROM sys.columns.
The huge difference between SQL Server 2019 and 2022 and between Windows and Linux is what's strange about this. We only noticed this issue because SELECT * FROM sys.columns ran absolutely fine on 2019 and suddenly timed out on 2022.