Source: https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create/ Documentation version: v5.3.2 # CREATE NORMAL INDEX statement The CREATE NORMAL INDEX statement creates a normal index on a specific graph or temporary graph. You can specify the graph or temporary graph by using either of the following methods: - Add a [USE clause](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dql/clauses/use-graph/) before this statement to set the working graph. - Use [SESSION SET](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/sessions/set/) in advance to set the graph or temporary graph for the current session. If both methods are used, the graph specified in the USE clause takes precedence. If neither method is used, an error is returned. You can create a normal index on one or more properties of a single node type or edge type to speed up queries that filter or sort data based on the indexed properties. To create other types of indexes, see [CREATE VECTOR INDEX](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-vector/), [CREATE SPATIAL INDEX](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-geo/), and [CREATE FULLTEXT INDEX](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-fulltext/). Note An operation involving a non-default schema or an object in it requires access to the schema, either implicitly or through an explicit `USAGE` grant, as well as the privilege required for the operation. The schema access check and the privilege check for the requested operation are independent; satisfying one does not satisfy the other. Schema access control does not apply to temporary graphs or built-in procedures and functions. For more information, see [Schema access control](https://dev-docs.nebula-graph.io/v5.3.2/server-admin/authorization/schema-access-control/). ## Prerequisites - A graph or temporary graph is created. For more information, see [CREATE GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph/create/) and [CREATE TEMPORARY GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph-projection/create/). - To create a normal index on a graph, you must either be the owner of the graph, be granted to perform the action `INDEX` on the graph, or be granted to perform the action `CREATE NORMAL INDEX` on the used schema. For more information, see [Roles and privileges](https://dev-docs.nebula-graph.io/v5.3.2/server-admin/authorization/). - To create a normal index on a temporary graph, you must be the user with the role `ADMIN` or the owner of the temporary graph. ## Behavior and impact - After executing `CREATE NORMAL INDEX`, the system automatically starts a background index build job. This background job can appear as a `REPAIR_INDEX` job in `SHOW JOB` or `SHOW JOBS`. You do not need to manually trigger a separate repair operation for the new index to take effect. - Queries cannot use the new index until the build is complete. - While the index is being built, read and write requests can continue. However, the build process consumes additional I/O (and some CPU/memory) resources, which may increase query or write latency. - If index creation fails, the system automatically rolls back the failed creation. Starting from 5.2, failed index creation is rolled back automatically, so no separate repair operation is needed. ## Syntax diagramsource create_index_statement index_property_list ```` create_index_statement ::= 'CREATE' 'NORMAL'? 'INDEX' ('IF NOT EXISTS')? index_name 'ON' ( ( ('NODE' | 'VERTEX') 'TYPE'? node_type_name ) | ( ('EDGE'|'RELATIONSHIP') 'TYPE'? edge_type_name ) ) '(' index_property_list ')' index_property_list ::= ( property_name ('ASC' | 'DESC')? ) ( ',' ( property_name ('ASC' | 'DESC')? ) )* ```` ## Parameters ### `NORMAL` Explicitly specifies that the index type to create is a normal index. This keyword can be omitted. ### `IF NOT EXISTS` This clause checks whether an index with the same name already exists. If it does, the index is not created and no error is raised. If this clause is not specified and an index with the same name already exists, an error is raised. ### `index_name` The name of the index to be created. The name is a regular identifier and must be unique among all index types within the same graph. For more information about identifiers, see [Rules for naming identifiers](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/overview/keywords-identifiers/#rules_for_naming_identifiers). ### `node_type_name` The name of the node type on which to create the index. You can create multiple indexes on the same node type based on different properties. ### `edge_type_name` The name of the edge type on which to create the index. You can create multiple indexes on the same edge type based on different properties. ### `index_property_list` The list of properties for the index. At least one property must be specified. When creating a normal index on multiple properties, the order of properties in the index matches the order specified in `index_property_list`. Therefore, when filtering or sorting data based on indexed properties, it is recommended to write queries following the property order in the index to optimize query performance. ### `property_name` The name of a property of the node type or edge type to index. The value type of the property cannot be `LIST`, `SET`, `MAP`, `VECTOR`, or `GEOGRAPHY`. For edge type indexes, the system fields `_src` (source node) and `_dst` (destination node) can also be used as index properties. When `_src` or `_dst` is placed as the first column in the index property list, this creates a vertex-centric index. For more information, see [Vertex-centric indexes](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create/#vertex-centric_indexes) below. ### `ASC | DESC` The sort order of property values in the index. - `ASC`: The default value. Sorts property values in ascending order. - `DESC`: Sorts property values in descending order. For sorting rules of different data types, see [Comparison predicates](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/predicates/comparison/). ## Vertex-centric indexes ### Concept A vertex-centric index is an edge index organized around nodes. In graph traversal scenarios, finding edges associated with a specific node is one of the most common operations. If a node has a large number of associated edges (e.g., a super node), traversing all edges and filtering them one by one can be very expensive. A vertex-centric index places the system field `_src` (source node) or `_dst` (destination node) as the first column of an edge index, allowing queries to quickly locate edges for a specific node and further filter them using subsequent index columns, thereby avoiding a full edge scan. A vertex-centric index is not a separate index type but a special way to build a normal edge index. It uses the standard `CREATE NORMAL INDEX` syntax. You simply place `_src` or `_dst` as the first column in the index property list. ### Use cases - Find qualifying outgoing edges from a specific source node: use `_src` as the first index column. - Find incoming edges to a specific destination node: use `_dst` as the first index column. - Filter edges on super nodes: when a node has a large number of associated edges, a vertex-centric index can significantly reduce the number of edges that need to be scanned. ### Auto-selection The optimizer can automatically select vertex-centric indexes during edge-scan planning when the query's `WHERE` clause contains at least one filter condition on an edge property (e.g., `w.rate >= 3`). Specifically, auto-selection requires a usable vertex-centric index whose key columns match the scan direction (outgoing uses a `_src`-leading index, incoming uses a `_dst`-leading index) and cover the filtered edge property. When these conditions are met, you do not need to specify an index hint. If the query does not filter on any edge property (i.e., only the anchor vertex ID is used to locate edges), the optimizer will not auto-select a vertex-centric index. This is because without an edge property filter, the vertex-centric index can only utilize its leading `_src`/`_dst` column, which offers no advantage over the default edge-table prefix scan. You can still use an explicit hint to force a specific vertex-centric index when needed. ### Limitations - Applicable only to edge type indexes, not to node type indexes. - `_src` or `_dst` can only be placed as the first column in the index property list. - Creating vertex-centric indexes on undirected edge types is not supported. - Indexes starting with `_src` and indexes starting with `_dst` serve different query directions. To speed up both outgoing and incoming edge queries, you need to create two separate indexes. - All other limitations of normal indexes also apply (e.g., you cannot create an index on a `LIST` type property). ## Examples The following examples are based on the graph `movie` and the temporary graph `#movie_temporary_graph` created in [CREATE GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph/create/) and [CREATE TEMPORARY GRAPH](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph-projection/create/) respectively. ### Create a normal index on a node type in a graph ```` ''' USE movie CREATE NORMAL INDEX IF NOT EXISTS idx_actor_age ON NODE Actor ( birthDate ASC ) ''' ```` This creates an ascending normal index named `idx_actor_age` on the `birthDate` property of the `Actor` node type. ### Create a normal index on an edge type in a graph ```` ''' USE movie CREATE NORMAL INDEX IF NOT EXISTS idx_watch_rating ON EDGE Watch ( rate DESC ) ''' ```` This creates a descending normal index named `idx_watch_rating` on the `rate` property of the `Watch` edge type. ### Create a normal index on a temporary graph ```` ''' USE #movie_temporary_graph CREATE NORMAL INDEX IF NOT EXISTS idx_actor_age_temp ON NODE Actor ( birthDate ASC ) ''' ```` ```` ''' USE #movie_temporary_graph CREATE NORMAL INDEX IF NOT EXISTS idx_watch_rating_temp ON EDGE Watch ( rate DESC ) ''' ```` ### Create a vertex-centric index Create a vertex-centric index with `_src` as the first column to speed up finding watch records from a specific user, filtered by rating: ```` ''' USE movie CREATE NORMAL INDEX IF NOT EXISTS idx_watch_src_rate ON EDGE Watch ( _src ASC, rate DESC ) ''' ```` Create a vertex-centric index with `_dst` as the first column to speed up finding all users who watched a specific movie, filtered by rating: ```` ''' USE movie CREATE NORMAL INDEX IF NOT EXISTS idx_watch_dst_rate ON EDGE Watch ( _dst ASC, rate DESC ) ''' ```` ### Auto-selection of vertex-centric indexes When the query has an edge property filter, the optimizer automatically selects the appropriate vertex-centric index. Query outgoing edges by source node: ```` ''' PROFILE USE movie MATCH (a:Person)-[w:Watch]->(m:Movie) WHERE a.id > 100 AND w.rate >= 3 RETURN m.name, w.rate ORDER BY w.rate DESC LIMIT 20 ''' ```` Query incoming edges by destination node: ```` ''' PROFILE USE movie MATCH (m:Movie{id:101})<-[w:Watch]-(a:Person) WHERE a.id > 100 AND w.rate >= 3 RETURN a.id, w.rate ORDER BY w.rate DESC LIMIT 20 ''' ```` Use the `PROFILE` or `EXPLAIN` command to verify the execution plan. If it contains an `IndexScan` operator referencing a vertex-centric index name (e.g., `idx_watch_src_rate` or `idx_watch_dst_rate`), the vertex-centric index is in effect. For more information, see [EXPLAIN](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-admin/tuning/explain/) and [PROFILE](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-admin/tuning/profile/). Note If the query does not filter on any edge property (e.g., no condition like `w.rate >= 3`), the optimizer will not auto-select a vertex-centric index. In this case, you can still use an explicit index hint to force its use (e.g., `MATCH (a:Person)-[w:Watch/*+ INDEX(idx_watch_src_rate) */]->(m:Movie)`). For more information about hints, see [Configure index hints](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/executions/hints/).