JSON Index Seek

Introduction

The JSON Index Seek is not really an actual operator. You can encounter it in graphical execution plans in SSMS (and other tools), but if you look at the underlying XML of the execution plan, you will see that it is actually an Index Seek (or Clustered Index Seek – see below) operator. Front end tools such as SSMS will present it as a JSON Index Seek when the IndexKind subproperty in the Object property group is equal to Json.

JSON indexes are implemented as a hidden internal node table, with a clustered index and one or two nonclustered indexes (see here for more details). The JSON Index Seek operator can target any one of these. There is nothing in the graphical execution plan, or in the execution plan XML, to distinguish a JSON Index Seek that targets the clustered index from one that targets one of the nonclustered indexes.

Visual appearance in execution plans

Depending on the tool being used, an Index Seek operator with a target that has its IndexKind property equal to Json is displayed in a graphical execution plan as shown below:

SSMS and ADS
(current versions)

Legacy SSMS

Plan Explorer

Paste The Plan

(not supported)

(shown as Index Seek or Clustered Index Seek)

(not supported)

Algorithm

The JSON Index Seek is not a real operator but merely a visual indicator that an Index Seek or Clustered Index Seek operator is targeting a JSON index. Please check the appropriate pages for a full description of the algorithms of those operators.

Operator properties

The properties below are specific to the JSON Index Seek operator, or have a specific meaning when appearing on it. For all other properties, see Common properties. Properties that are included on the Common properties page but are also included below for their specific meaning for the JSON Index Seek operator are marked with a *.

(Note that most of these properties are exactly the same as for the Index Seek operator; they are repeated here for ease of use).

Property nameDescription
Actual Number of Rows ReadThis is the number of rows that was read by the operator as it was navigating the index. In a parallel execution plan, this property shows a breakdown of rows on each individual thread.
The difference between this property and the Actual Number of Rows property represents the number of rows that was read but not returned due to the Predicate property, or because the parent operator stopped asking for more rows before the end of data was reached.
Note that this property may report incorrect values when the Predicate property contains a PROBE.
Only available in execution plan plus run-time statistics. When the actual number of rows read is equal to zero, this property is omitted.
Actual Partition CountThis is the number of partitions within a partitioned table that were accessed at least once during execution.
Only available in execution plan plus run-time statistics and only when the Partitioned property is included and set to True.
Actual Partitions AccessedThis property lists all the partitions within a partitioned table that were accessed at least once during execution. In the execution plan XML, this is actually stored as one or more PartitionRange elements, each with a Start and End property. In tools such as SSMS, this is displayed as a semicolon separated list of ranges, where every single-partition range is displayed as a number instead. So for instance, “2-4;7;10-11” represents that partitions 2, 3, 4, 7, 10, and 11 were accessed at least once.
Only available in execution plan plus run-time statistics and only when the Partitioned property is included and set to True.
Defined Values *For a JSON Index Seek, this property lists the columns read from the index and returned to the calling operator. It is therefore the same as the Output List property.
Estimated Number of Rows to be ReadThis is an estimate of the number of rows that will be read by the operator as it is navigating the index. The higher the difference between this number and the Table Cardinality, the more effective the use of this JSON Index Seek (as opposed to a Clustered Index Scan of the base table) is estimated to be.
The difference between this property and the Estimated Number of Rows property represents the number of rows that is estimated to be read but not returned due to the Predicate property.
Note that this property is computed without taking the effect of a row goal (if any) into account. If the EstimateRowsWithoutRowGoal property is present, then you need to compare that, instead of the Estimated Number of Rows, to the Estimated Number of Rows to be Read property for a proper assessment of the estimated selectivity of the Predicate.
Forced IndexThis property is set to true if the use of this index was forced through an index hint in the query.
ForceScanThis property is set to true if the query used a FORCESCAN hint to force the use of a scan operator even if the optimizer would rather use a seek operator. On a JSON Index Seek operator, it is therefore always false.
ForceSeekThis property is set to true if the query used a FORCESEEK hint to force the use of a seek operator even if the optimizer would rather use a scan operator.
NoExpandHintThis property is set to true if the NOEXPAND hint was used in the query to force the optimizer to use indexes on an indexed view.
ObjectThis property lists the index that is being navigated by the JSON Index Seek operator, using four part naming (database, schema, table, index) and optionally followed by a table alias.
The subproperties of the Object property represent the alias and the four name parts separately, but also include two additional properties:
  • Index Kind: Represents what kind of index is seeked. For a JSON Index Seek, this can only be Json.
  • Storage: Determines the storage type of the index. For a JSON Index Seek, this can only be RowStore.
OrderedThis property is always equal to True for a JSON Index Seek.
PartitionedThis property is present and set to True when the index read by the JSON Index Seek is a partitioned index.
PredicateWhen present, this property defines a logical test to be applied to all rows that are read by the JSON Index Seek. Only rows for which the predicate evaluates to True are returned. When possible, the JSON Index Seek operator will push this predicate into the storage engine to prevent extra roundtrips between the operator and the storage engine.
Note that a Predicate on a JSON Index Seek does not reduce the amount of rows that is touched by the operator. The difference between the Actual Number of Rows and the Number of Rows Read property (or their estimated counterparts) shows how many rows were read but not returned. This can be used to gauge how useful an index would be that better supports the search predicates.
Scan DirectionFor range seeks, this property specifies whether the data has to be returned in normal index order (“FORWARD”) or reverse index order (“BACKWARD”).
The BACKWARD option is not available for memory-optimized indexes.
Seek PredicatesA collection of one or more Seek Keys that are used to navigate the index and locate the rows to be read. See the main text for more information.
Table CardinalityThis property shows the number of rows in the index’s table when the plan was last compiled. For a JSON Index Seek, this refers to the hidden internal node table.

Implicit properties

This table below lists the behavior of the implicit properties for the JSON Index Seek operator.

(Note that most of these properties are exactly the same as for the Index Seek operator; they are repeated here for ease of use.

Property nameDescription
Batch Mode enabledThe JSON Index Seek operator supports row mode execution only.
BlockingThe JSON Index Seek operator is non-blocking.
Memory requirementThe JSON Index Seek operator does not have any special memory requirement.
Order-preservingThe JSON Index Seek operator imposes an order, as specified in the Scan Direction property. If the Seek Predicates property specifies more than one Seek Keys specification, the optimizer always ensures that these are in the correct corresponding order.
Parallelism awareWhen the JSON Index Seek operator is used for range scans in a parallel section of an execution plan, it uses the “Parallel Page Supplier”. See Index Scan for more details.
Segment awareThe JSON Index Seek operator is not segment aware.

Change log

(Does not include minor changes, such as adding, removing, or changing hyperlinks, correcting typos, and rephrasing for clarity).

July 19, 2026: Added.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close