From 877b2d9172b4428a2ac710bd6bcf901c7e96c69d Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Thu, 22 Oct 2015 11:31:52 +0200 Subject: [PATCH 1/2] Add notes about the Explainer tool. --- Documentation/Books/Users/Aql/Optimizer.mdpp | 31 +++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/Documentation/Books/Users/Aql/Optimizer.mdpp b/Documentation/Books/Users/Aql/Optimizer.mdpp index 4012ff1cfc..d5b4068a1c 100644 --- a/Documentation/Books/Users/Aql/Optimizer.mdpp +++ b/Documentation/Books/Users/Aql/Optimizer.mdpp @@ -12,29 +12,46 @@ meaning that an optimization should not modify the result of a query. A notable to this is that the optimizer is allowed to change the order of results for queries that do not explicitly specify how results should be sorted. - !SUBSECTION Execution plans The `explain` command can be used to query the optimal executed plan or even all plans the optimizer has generated. Additionally, `explain` can reveal some more information about the optimizer's view of the query. -Here's an example that shows the execution plan for a simple query, using the `explain` -method of `ArangoStatement`: +!SUBSECTION Inspecting plans using the explain helper - @startDocuBlockInline AQLEXP_01_explainCreate - @EXAMPLE_ARANGOSH_OUTPUT{AQLEXP_01_explainCreate} +The `explain` method of `ArangoStatement` as shown in the next chapters creates very verbose output. +You can work on the output programaticaly, or use this handsome tool that we created +to generate a more human readable representation. + +You may use it like this: (we disable syntax highlighting here) + + @startDocuBlockInline AQLEXP_01_axplainer + @EXAMPLE_ARANGOSH_OUTPUT{AQLEXP_01_axplainer} ~addIgnoreCollection("test") db._create("test"); for (i = 0; i < 100; ++i) { db.test.save({ value: i }); } db.test.ensureIndex({ type: "skiplist", fields: [ "value" ] }); + var explain = require("org/arangodb/aql/explainer").explain; + explain("FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value", {colors:false}); + @END_EXAMPLE_ARANGOSH_OUTPUT + @endDocuBlock AQLEXP_01_axplainer + + +!SUBSECTION Execution plans in detail + +Lets have a look at the raw json output of the same execution plan +using the `explain` method of `ArangoStatement`: + + @startDocuBlockInline AQLEXP_01_explainCreate + @EXAMPLE_ARANGOSH_OUTPUT{AQLEXP_01_explainCreate} stmt = db._createStatement("FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value"); stmt.explain(); @END_EXAMPLE_ARANGOSH_OUTPUT @endDocuBlock AQLEXP_01_explainCreate -The result details will be very verbose so they are not shown here in full. Instead, -let's take a closer look at the results step by step. +The as you can see, result details are very verbose so we will not shown them in full in the next +sections. Instead, lets take a closer look at the results step by step. !SUBSUBSECTION Execution nodes From d1386ef8eeb63d971de19fa841cf62cdf4d47411 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Thu, 22 Oct 2015 11:32:40 +0200 Subject: [PATCH 2/2] New examples. --- .../Examples/AQLEXP_01_axplainer.generated | 44 +++++++++++ .../graph_create_knows_sample.generated | 75 +++++++++++++++++++ .../graph_create_social_sample.generated | 69 +++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 Documentation/Examples/AQLEXP_01_axplainer.generated create mode 100644 Documentation/Examples/graph_create_knows_sample.generated create mode 100644 Documentation/Examples/graph_create_social_sample.generated diff --git a/Documentation/Examples/AQLEXP_01_axplainer.generated b/Documentation/Examples/AQLEXP_01_axplainer.generated new file mode 100644 index 0000000000..51f8f13575 --- /dev/null +++ b/Documentation/Examples/AQLEXP_01_axplainer.generated @@ -0,0 +1,44 @@ +arangosh> db._create("test"); +[ArangoCollection 1092291992475, "test" (type document, status loaded)] +arangosh> for (i = 0; i < 100; ++i) { db.test.save({ value: i }); } +arangosh> db.test.ensureSkiplist("value"); +{ + "id" : "test/1092311980955", + "type" : "skiplist", + "fields" : [ + "value" + ], + "unique" : false, + "sparse" : false, + "isNewlyCreated" : true, + "code" : 201 +} +arangosh> var explain = require("org/arangodb/aql/explainer").explain; +arangosh> explain("FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value", {colors:false}); +Query string: + FOR i IN test FILTER i.value > 97 SORT i.value RETURN i.value + +Execution plan: + Id NodeType Est. Comment + 1 SingletonNode 1 * ROOT + 9 IndexNode 50 - FOR i IN test /* skiplist index scan */ + 5 CalculationNode 50 - LET #3 = i.`value` /* attribute expression */ /* collections used: i : test */ + 8 ReturnNode 50 - RETURN #3 + +Indexes used: + By Type Collection Unique Sparse Selectivity Fields Ranges + 9 skiplist test false false n/a [ `value` ] i.`value` > 97 + +Optimization rules applied: + Id RuleName + 1 move-calculations-up + 2 move-filters-up + 3 remove-redundant-calculations + 4 remove-unnecessary-calculations + 5 move-calculations-up-2 + 6 move-filters-up-2 + 7 use-indexes + 8 remove-filter-covered-by-index + 9 use-index-for-sort + + diff --git a/Documentation/Examples/graph_create_knows_sample.generated b/Documentation/Examples/graph_create_knows_sample.generated new file mode 100644 index 0000000000..7d1f9f60c8 --- /dev/null +++ b/Documentation/Examples/graph_create_knows_sample.generated @@ -0,0 +1,75 @@ +arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js"); +arangosh> var g = examples.loadGraph("knows_graph"); +arangosh> db.persons.toArray() +[ + { + "name" : "Charlie", + "_id" : "persons/charlie", + "_rev" : "1092164590491", + "_key" : "charlie" + }, + { + "name" : "Bob", + "_id" : "persons/bob", + "_rev" : "1092164328347", + "_key" : "bob" + }, + { + "name" : "Eve", + "_id" : "persons/eve", + "_rev" : "1092164983707", + "_key" : "eve" + }, + { + "name" : "Dave", + "_id" : "persons/dave", + "_rev" : "1092164787099", + "_key" : "dave" + }, + { + "name" : "Alice", + "_id" : "persons/alice", + "_rev" : "1092164131739", + "_key" : "alice" + } +] +arangosh> db.knows.toArray(); +[ + { + "_id" : "knows/1092165835675", + "_rev" : "1092165835675", + "_key" : "1092165835675", + "_from" : "persons/eve", + "_to" : "persons/alice" + }, + { + "_id" : "knows/1092165639067", + "_rev" : "1092165639067", + "_key" : "1092165639067", + "_from" : "persons/bob", + "_to" : "persons/dave" + }, + { + "_id" : "knows/1092165245851", + "_rev" : "1092165245851", + "_key" : "1092165245851", + "_from" : "persons/alice", + "_to" : "persons/bob" + }, + { + "_id" : "knows/1092165442459", + "_rev" : "1092165442459", + "_key" : "1092165442459", + "_from" : "persons/bob", + "_to" : "persons/charlie" + }, + { + "_id" : "knows/1092166032283", + "_rev" : "1092166032283", + "_key" : "1092166032283", + "_from" : "persons/eve", + "_to" : "persons/bob" + } +] +arangosh> examples.dropGraph("knows_graph"); +true diff --git a/Documentation/Examples/graph_create_social_sample.generated b/Documentation/Examples/graph_create_social_sample.generated new file mode 100644 index 0000000000..977349a549 --- /dev/null +++ b/Documentation/Examples/graph_create_social_sample.generated @@ -0,0 +1,69 @@ +arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js"); +arangosh> var graph = examples.loadGraph("social"); +arangosh> db.female.toArray() +[ + { + "name" : "Diana", + "_id" : "female/diana", + "_rev" : "1092171340699", + "_key" : "diana" + }, + { + "name" : "Alice", + "_id" : "female/alice", + "_rev" : "1092170619803", + "_key" : "alice" + } +] +arangosh> db.male.toArray() +[ + { + "name" : "Bob", + "_id" : "male/bob", + "_rev" : "1092170947483", + "_key" : "bob" + }, + { + "name" : "Charly", + "_id" : "male/charly", + "_rev" : "1092171144091", + "_key" : "charly" + } +] +arangosh> db.relation.toArray() +[ + { + "type" : "friend", + "_id" : "relation/bobAndDiana", + "_rev" : "1092172323739", + "_key" : "bobAndDiana", + "_from" : "male/bob", + "_to" : "female/diana" + }, + { + "type" : "married", + "_id" : "relation/charlyAndDiana", + "_rev" : "1092172127131", + "_key" : "charlyAndDiana", + "_from" : "male/charly", + "_to" : "female/diana" + }, + { + "type" : "friend", + "_id" : "relation/aliceAndCharly", + "_rev" : "1092171930523", + "_key" : "aliceAndCharly", + "_from" : "female/alice", + "_to" : "male/charly" + }, + { + "type" : "married", + "_id" : "relation/aliceAndBob", + "_rev" : "1092171668379", + "_key" : "aliceAndBob", + "_from" : "female/alice", + "_to" : "male/bob" + } +] +arangosh> examples.dropGraph("social"); +true