@@ -1674,7 +1674,28 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16741674 ps.object_id
16751675 HAVING
16761676 SUM(ps.row_count) >= @min_rows
1677- )
1677+ )' ;
1678+
1679+ /*
1680+ Only filter on index usage when the caller actually asked for a read or write
1681+ minimum. sys.dm_db_index_usage_stats has no row for an index that hasn't been
1682+ touched since usage stats were last reset, and on Azure SQL DB / Hyperscale
1683+ those stats reset on every failover and scaling operation. Appending this
1684+ EXISTS unconditionally drops every index whenever the DMV is empty, which
1685+ silently empties #filtered_objects and makes the procedure exit with no result
1686+ set and no error. With the defaults (@min_reads = 0, @min_writes = 0) we want
1687+ to analyze every index, including never-used ones (the whole point of the tool).
1688+ @min_reads and @min_writes are validated to non-NULL, non-negative above.
1689+ */
1690+ IF @min_reads > 0
1691+ OR @min_writes > 0
1692+ BEGIN
1693+ IF @debug = 1
1694+ BEGIN
1695+ RAISERROR (' adding index usage reads/writes filter' , 0 , 0 ) WITH NOWAIT ;
1696+ END ;
1697+
1698+ SET @sql + = N'
16781699 AND EXISTS
16791700 (
16801701 SELECT
@@ -1688,7 +1709,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16881709 SUM(ius.user_seeks + ius.user_scans + ius.user_lookups) >= @min_reads
16891710 OR
16901711 SUM(ius.user_updates) >= @min_writes
1691- )
1712+ )' ;
1713+ END ;
1714+
1715+ SET @sql + = N'
16921716 OPTION(RECOMPILE);
16931717 ' ;
16941718
@@ -1735,15 +1759,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17351759 BEGIN
17361760 IF @debug = 1
17371761 BEGIN
1738- RAISERROR (' No rows inserted into #filtered_objects from %s, continuing to next database.. .' , 10 , 0 , @current_database_name) WITH NOWAIT ;
1762+ RAISERROR (' No rows inserted into #filtered_objects from %s; no indexes met the analysis criteria .' , 10 , 0 , @current_database_name) WITH NOWAIT ;
17391763 END ;
17401764
1741- IF @get_all_databases = 0
1742- BEGIN
1743- RETURN ;
1744- END ;
1745-
1746- /* Get the next database and continue the loop */
1765+ /*
1766+ Advance the cursor instead of bare-RETURNing. A bare RETURN here (the old
1767+ single-database behavior) exited the procedure with no result set and no
1768+ error. Falling through lets the database surface in the 'DATABASES WITH NO
1769+ QUALIFYING OBJECTS' result set below, so the caller always gets feedback. In
1770+ single-database mode the cursor is now exhausted and the loop ends normally.
1771+ */
17471772 FETCH NEXT
17481773 FROM @database_cursor
17491774 INTO
0 commit comments