Indexes on small table needing to be constantly rebuilt when server busy - sql-server

In my SQL database (compatibility level SQL Server 2008, but on SQL Server 2012), I have a small table called Locations: 2036 rows in 21 pages.
"Select * from Locations" will return all rows in a split second. However, after moving to a virtual environment, under heavy load that SQL will hang until I rebuild indexes on that table: "ALTER INDEX ALL ON dbo.Locations REBUILD WITH (FILLFACTOR = 100)".
And then it's fine. Until it slows down again and I need to rebuild again -- sometimes 5 sec later!
When I run: "DBCC CHECKTable (Locations);", I get "DBCC results for 'Locations'.There are 2036 rows in 21 pages for object "Locations".
Any ideas what this could be or where I should start looking?

A query on the whole table;
Select * from Locations
will not reference any indexes, and I therefore believe its pure coincidence that an index rebuild is 'solving' the problem. Have you checked for process thread locks on the SQL Server? There may be some contention on the table that is locking that query.

Related

Select on External table running very very slow on Azure SQL

We have external table created, we need to run select on the table and select all the records, the select runs very very slow. Its not completing even after 30 mins, the table contains around 2millon recs
We also need to query this table from another DB and even this runs very very slow, doesn't return even after 30 mins.
Select is of the form:
select col1, col2,...col3 from ext_table;
Need help in:
1. Any suggestions on reducing the time taken for execution?
Note: we need to select entire content of the table so where condition might not be used.
Thanks in advance.
If you are not using the WHERE clause to push parameters to the remote database, then there is no way to optimize the performance of the query. You are returning the whole table.
My suggestion is to use SQL Data Sync to have a local copy of the table on this SQL Database that synchronizes with the remote Azure SQL Database at X interval of time.

SQL server linked server to PostgreSQL query conversion of TOP clause is not converted

I created a SQL linked server to connect to PostgreSQL 11, and issue a query like this
SELECT TOP 1 *
FROM [LinkedServer_PostgreSQL].[DBname].[dbo].[TableName] a;
It is very slow and seems to take forever, I ended up killing the query every time. Upon investigation, I found the query on the PostgreSQL server is selecting all rows, the TOP N row clause on the PostgreSQL is not converted. That's why the query cannot finish, because the table has more than 10 million rows.
As I cannot replace TOP clause using LIMIT clause on SQL server. This really beats me. Help, anyone?

Performance problems after updating statistics SQL Server 2014

I've received a database that was previously on SQL Server 2008R2 but was just put on a SQL Server 2014 instance. There were no maintenance tasks run of any kind run on the database since 2014 (e.g. Rebuilding of indexes, updating statistics, etc.).
Once we ran update statistics as part of our regularly scheduled maintenance that we do on a set schedule, the performance of some queries has taken a massive hit to the point where some select statements will seem to never finish.
The queries have some CASE...WHEN statements in them, but I wouldn't expect there to be such a performance hit. Does anybody have any thoughts on what might cause such issues?
I've tried updating the compatibility level to 120 since it was on 100 when the database first came in but, that didn't make any difference on the performance.
If you have only just moved the database, give the system some time to build up its execution plans and cache. Also, do your index maintenance and then something like this for the stats. Dont use sp_updatestats though as it just uses a sample of data not a full scan.
what results do you get for this:
SELECT
[sch].[name] + '.' + [so].[name] AS [TableName] ,
[ss].[name] AS [Statistic],
[sp].[last_updated] AS [StatsLastUpdated] ,
[sp].[rows] AS [RowsInTable] ,
[sp].[rows_sampled] AS [RowsSampled] ,
[sp].[modification_counter] AS [RowModifications],
Convert (decimal(18,2),(convert(numeric,[sp].[modification_counter]) / convert(numeric,[sp].[rows]) * 100)) as [Percent_changed]
FROM [sys].[stats] [ss]
JOIN [sys].[objects] [so] ON [ss].[object_id] = [so].[object_id]
JOIN [sys].[schemas] [sch] ON [so].[schema_id] = [sch].[schema_id]
OUTER APPLY [sys].[dm_db_stats_properties]([so].[object_id],
[ss].[stats_id]) sp
WHERE [so].[type] = 'U'
AND [sp].[modification_counter] > 0
And [sp].[last_updated] < getdate()-1
ORDER BY [Percent_changed] DESC

Is It possible to a rebuild Index with out taking instance offline?

I have this one NONCLUSTERED INDEX that's 85.71% total fragmentation and 55.35% page fullness.
Can this be done without taking my instance offline and not enterprise edition?
TITLE: Microsoft SQL Server Management Studio
------------------------------
Rebuild failed for Index 'idx_last_success_download'. (Microsoft.SqlServer.Smo)
For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.50.2500.0+((KJ_PCU_Main).110617-0038+)&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Rebuild+Index&LinkId=20476
------------------------------
ADDITIONAL INFORMATION:
An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
------------------------------
Lock request time out period exceeded. (Microsoft SQL Server, Error: 1222)
For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=10.50.2500&EvtSrc=MSSQLServer&EvtID=1222&LinkId=20476
------------------------------
BUTTONS:
OK
------------------------------
After Reorganized:
ALTER INDEX idx_last_success_download ON dbo.TERMINAL_SYNCH_STATS
REORGANIZE;
I'm still getting 85.71 fragmentation?
Using for my stats: DBCC SHOWCONTIG
DBCC SHOWCONTIG scanning 'TERMINAL_SYNCH_STATS' table...
Table: 'TERMINAL_SYNCH_STATS' (331148225); index ID: 38, database ID: 7
LEAF level scan performed.
- Pages Scanned................................: 7
- Extents Scanned..............................: 5
- Extent Switches..............................: 6
- Avg. Pages per Extent........................: 1.4
- Scan Density [Best Count:Actual Count].......: 14.29% [1:7]
- Logical Scan Fragmentation ..................: 85.71%
- Extent Scan Fragmentation ...................: 40.00%
- Avg. Bytes Free per Page.....................: 3613.9
- Avg. Page Density (full).....................: 55.35%
Lock time out is not a version issue
Yes it is possible to rebuild an index online.
You have a lock timeout. I suspect it is an active table and rebuild simply cannot acquire a lock.
Try a Reorganize
Reorganize and Rebuild Indexes
Please note in any case you dont have to take SQL server database or SQL Server instance offline to rebuild any index. Yes if you have Standard edition ONLINE index rebuild is not possible and you have to make sure application or some query is not accessing the table otherwise index rebuild would fail
What is output of
select ##Version
The erorr message
Lock request time out period exceeded. (Microsoft SQL Server, Error: 1222)
Only says that when index rebuild task was trying to get exlcusive lock on table, because during index rebuild index is dropped and recreated , it was not able to get hence the error message. It is not a threatening message. You can get this message both in standard and enterprise edition while rebuilding index.
Index rebuild is maintenance activity so should always be done when load on database is relatively very less or during mainteance window.
For solution try rebuilding when no body is accessing database or laod is very less
Try to run rebuild with specifying option WAIT_AT_LOW_PRIORITY
e.g. as below
ALTER INDEX idx_last_success_download ON dbo.TERMINAL_SYNCH_STATS
REBUILD WITH
( FILLFACTOR = 80, SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = ON,
ONLINE = ON (WAIT_AT_LOW_PRIORITY
(MAX_DURATION = 4 MINUTES, ABORT_AFTER_WAIT = BLOCKERS ) ),
DATA_COMPRESSION = ROW
);
For more info refer: https://msdn.microsoft.com/en-us/library/ms188388.aspx

Do all SQL server versions rebuild indexes automatically or have a default rebuild criteria?

Do all SQL server versions rebuild indexes automatically or have a default rebuild criteria? I understand statistics are rebuilt automatically but not sure if indexes do as well.
Rebuilding of indexes is not supported automatically in any version of Microsoft SQL Server - the reason being is that rebuilding indexes can potentially be very expensive operations, and so need careful scheduling and planning.
In many environments special scripts will be written to handle this, for example:
http://weblogs.sqlteam.com/tarad/archive/2008/09/03/Defragmenting-Indexes-in-SQL-Server-2005.aspx
Note that whilst SQL can automatically update statistics for you in many cases there is a performance gain to be had by managing these more carefully as well.
As people have mentioned here, your indexes do not automatically rebuild. This is quite a big problem in SQL Server, as your indexes will fragment over time. Your could find your indexes are 95% plus fragmented, affecting query performance badly.
Here is a simple query to check fragmentation on your existing indexes:
DECLARE #DBNAME VARCHAR(130);
SET #DBNAME = 'MYDBNAME';
DECLARE #DBID INT;
SET #DBID = DB_ID(#DBNAME);
SELECT
OBJECT_ID AS objectID
, index_id AS indexID
, avg_fragmentation_in_percent AS fragmentation
, page_count
INTO #indexDefragList
FROM
sys.dm_db_index_physical_stats
(#DBID, NULL, NULL , NULL, N'Limited')
WHERE
index_id > 0
OPTION (MaxDop 1);
SELECT
i.[name] as indexname,
d.fragmentation,
d.page_count
FROM
#indexDefragList d
INNER JOIN sys.indexes i
ON d.objectid = i.object_id
ORDER BY
d.fragmentation DESC
DROP TABLE #indexDefragList
This will return a list of all indexes in your current DB with their fragmentation in %.
You can easily build a script to automatically rebuild or reorganise them. There is a great article from SQLFool on this including a complete pre-made script.
To expand on what Chris has said:
With regard to statistics, columns not covered by an index will not have their statistics updated by rebuilding all indexes. They may periodically be updated by SQL Server however you may need to do this yourself with the UPDATE STATISTICS statement.
SQL Server 2005 determines whether to update statistics automatically based on changes to column modification counters (colmodctrs).
A statistics object is considered out of date in the following cases:
1.The table size has gone from 0 to >0 rows.
2.The number of rows in the table when the statistics were gathered was 500 or less, and the colmodctr of the leading column of the statistics object has changed by more than 500 since then.
3.The table had more than 500 rows when the statistics were gathered, and the colmodctr of the leading column of the statistics object has changed by more than 500 + 20% of the number of rows in the table when the statistics were gathered
You may find the following reference regarding statistics of use:
http://blogs.technet.com/rob/archive/2008/05/16/sql-server-statistics.aspx
Hope this helps but feel free to pose further queries.
Cheers, John
As #Chris noted, indexes are not rebuilt automatically in any SQL Server version. Proper index maintenance is often missing at sites with no dedicated DBA role, and often when databases are simply moved from development into production (along with Transaction Log maintenance).
SQL Server 2005+ has the ability to do online index reorganises and offline full rebuilds.
It has to be schedule and arranged yourself.
When sorting it out, it depends on the size of your tables and maintenance window.
Also, statistics are rebuilt automatically when the indexes are rebuilt but can be scheduled separately.
For a quick fix, assuming a nice long maintenance window and not too big (upto a few 100 GBs), just schedule this:
EXEC sp_msforeachtable 'SET QUOTED_IDENTIFIER ON ALTER INDEX ALL ON ? REBUILD WITH (FILLFACTOR = 90)'
Edit: only for > SQL 2005 this SQL

Resources