DBCC REINDEX after an update on a table - sybase

I am accessing table with a simple update query, however it gave me this error:
Error : Index id 3 on table id 128716480 cannot be used in the optimization of a query as it is >SUSPECT. Please have the SA run DBCC REINDEX on the specified table.
Will running DBCC REINDEX do the trick ?

Yes. Running that will rebuild the tables indexes. The only time that may not work is if you are dealing with system tables/system indexes.

Related

Simple query with different execution plan when executed from SQL Job agent

I have this quite simple query:
IF EXISTS (SELECT 1 FROM system.RawEvent_pool1 WHERE ProcessedDate IS NULL)
EXECUTE [system].[usp_ProcessAuditData] '1'
I have a filtered index on system.RawEvent_pool1.
It is filtered on ProcessedDate IS NULL
(ProcessedDate is included in the index)
So the index should be a perfect match for this query.
From the actual execution plan, I can tell, that when executed from Management Studio the index is used as expected.
But when executing the exact same query on the same database from a SQL Job Agent, the index is not used.
Instead, the query plan uses the clustered index on the primary key for the table.
This I can see in the Query Store.
Additional info: The job is executed under a different account.
Is there any logical explanation for this behavior?
Then I would love to hear it :-)
Found the reason.
The SQL Job Agent has 'QUOTED_IDENTIFIER' set to 'OFF' by default.
Executing 'SET QUOTED_IDENTIFIER ON' will make the statement use the expected execution plan
But I still have no clue why this works.

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

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.

Reset SQL Server Index usage

I use below query to analyze usage of index in SQL Server.
SELECT *
FROM sys.dm_db_index_usage_stats A
WHERE A.database_id = DB_ID()
How can reset all data from this system table?
What do you mean by reset .. do you want to reset the index usage statistics in the table?
Taken from Here
Usage statistics: These are found in sys.dm_db_index_usage_stats.
Index usage statistics keep track of things like seeks and scans from
SELECT queries. They are not persisted and get reset on restart of sql
server. These statistics also get reset if the underlying index is
rebuilt "ALTER INDEX ... REBUILD", but not with "ALTER INDEX ...
REORG"
As said, you can't reset it manually. Take a look at this post which certainly says the same
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/08eb7b79-64a3-4475-bfc3-69715aec8381/resetting-dmdbindexusagestats-without-restarting-or-detaching-a-database
Like mentioned, you cannot truly reset it without restarting the SQL Server.
BUT
Why do you want to reset it? Probably because you have made changes to your indexes and simply want to see how the usage has changed, am I right?
In this case you can hardcode the existing values into your query and subtract it to get new stats from this point.
By "hardcoding" I mean joining with a VALUES pseudo-table, something like this
--your SELECT goes here
--your FROM goes here
--add this JOIN
JOIN ( VALUES('IX_index1', 2412727),
('IX_index2', 1630517),
('IX_index3', 514129)) o(name, seeks) ON o.name=indexes.name
-- rest of your query
Now you can add this to your SELECT to get the difference:
SELECT dm_db_index_usage_stats.user_seeks - o.seeks AS newseeks
So in a nutshell:
SELECT the existing usage stats from dm_db_index_usage_stats
do some copy-pasting magic to get the existing stats and hardcode into your query
see the changes

User created statistics adding dependency on columns on sql server

Recently I have dropped all automatically created statistics (named _WA_Sys_%) and run the following T-SQL command to create statistics for all columns of the database :
EXEC sp_createstats #indexonly = 'NO', #fullscan = 'FULLSCAN', #norecompute ='NO'
All worked fine, until I had to drop a column in a table, then an error 5074 occured, indicating that statistics should be dropped before dropping the column.
Is there a way to get SQL Server to drop silently user created statistics when a column is dropped ?
I don't think you can make SQL server do it silently, as this is a common problem for people using user statistics. There is a way to drop relevant statistics with a custom query - would it work for your needs?

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