diff --git a/internal/database/mariadb.go b/internal/database/mariadb.go index fd9409e..c9b22a3 100644 --- a/internal/database/mariadb.go +++ b/internal/database/mariadb.go @@ -86,12 +86,8 @@ func (m *MariaDB) InitializeSchema() error { CONSTRAINT fk_from FOREIGN KEY (from_id) REFERENCES assets (id), CONSTRAINT fk_to FOREIGN KEY (to_id) REFERENCES assets (id), - INDEX full_relation_type_from_to_idx (type, from_id, to_id), - INDEX full_relation_type_to_from_idx (type, to_id, from_id), - INDEX full_relation_from_type_to_idx (from_id, type, to_id), - INDEX full_relation_from_to_type_idx (from_id, to_id, type), - INDEX full_relation_to_from_type_idx (to_id, from_id, type), - INDEX full_relation_to_type_from_idx (to_id, type, from_id))`) + INDEX type_from_idx (type, from_id), + INDEX type_to_idx (type, to_id))`) if err != nil { return fmt.Errorf("unable to create relations table: %v", err) } diff --git a/internal/knowledge/query_sql.go b/internal/knowledge/query_sql.go index e04037d..4b8ff98 100644 --- a/internal/knowledge/query_sql.go +++ b/internal/knowledge/query_sql.go @@ -141,7 +141,6 @@ func buildSQLConstraintsFromPatterns(queryGraph *QueryGraph, constrainedNodes ma // If no relationship of this node has been visited yet, then we have no information on this node. // Scan the assets table again for this particular node. if !relationToAssetExists { - if len(n.Labels) == 0 { from = append(from, SQLFrom{Value: "assets", Alias: alias}) } @@ -197,6 +196,7 @@ func buildSQLConstraintsFromPatterns(queryGraph *QueryGraph, constrainedNodes ma Table: "assets", Alias: alias, On: strings.Join(exp, " AND "), + Index: "PRIMARY", }) } @@ -236,14 +236,20 @@ func buildSQLConstraintsFromPatterns(queryGraph *QueryGraph, constrainedNodes ma } } + index := "" + if relation.Direction == Right && relation.LeftIdx == i { exps = append(exps, fmt.Sprintf("%s.from_id = %s%d.id", ralias, assetAliasPrefix, relation.LeftIdx)) + index = "type_from_idx" } else if relation.Direction == Right && relation.RightIdx == i { exps = append(exps, fmt.Sprintf("%s.to_id = %s%d.id", ralias, assetAliasPrefix, relation.RightIdx)) + index = "type_to_idx" } else if relation.Direction == Left && relation.LeftIdx == i { exps = append(exps, fmt.Sprintf("%s.to_id = %s%d.id", ralias, assetAliasPrefix, relation.LeftIdx)) + index = "type_to_idx" } else if relation.Direction == Left && relation.RightIdx == i { exps = append(exps, fmt.Sprintf("%s.from_id = %s%d.id", ralias, assetAliasPrefix, relation.RightIdx)) + index = "type_from_idx" } else { // If a relationship is undirected optimize, err := isRelationOptimizable(queryGraph, *relation) @@ -283,6 +289,7 @@ func buildSQLConstraintsFromPatterns(queryGraph *QueryGraph, constrainedNodes ma Table: "relations", Alias: ralias, On: strings.Join(exps, " AND "), + Index: index, }) } diff --git a/internal/knowledge/sql_builder.go b/internal/knowledge/sql_builder.go index 0c40d2c..8b1944a 100644 --- a/internal/knowledge/sql_builder.go +++ b/internal/knowledge/sql_builder.go @@ -30,6 +30,7 @@ type SQLJoin struct { Table string Alias string On string + Index string } // SQLInnerStructure represent a SQL inner structure with an optional alias name @@ -241,7 +242,13 @@ func buildBasicSingleSQLSelect( var sb strings.Builder for _, j := range joinEntries { - sb.WriteString(fmt.Sprintf("\nJOIN %s %s ON %s", j.Table, j.Alias, j.On)) + sb.WriteString(fmt.Sprintf("\nJOIN %s %s ", j.Table, j.Alias)) + + if j.Index != "" { + sb.WriteString(fmt.Sprintf("FORCE INDEX FOR JOIN (%s) ", j.Index)) + } + + sb.WriteString(fmt.Sprintf("ON %s", j.On)) } joins := sb.String()