arangodb / arangodb-php

PHP ODM for ArangoDB
https://www.arangodb.com
Apache License 2.0
183 stars 43 forks source link

long query make arango stop #204

Closed mhseptiadi closed 7 years ago

mhseptiadi commented 7 years ago

Im pretty new to arangodb. So im sorry if my question is seem stupid :D.

Currently when I run some long query using arangodb-php lib, soon the arango service in my server will collapse and need to be started again. However if i run my query directly using arangosh, it run perfectly even though it takes long time. On the other hand, when i check the arangod.log there is a warning about query slow.

Example of long query:

`FOR result IN words FILTER ( like(result._key, '%+cara+%', true) like(result._key, 'cara+%', true)
like(result._key, '+cara%', true) ) && ( like(result._key, '%+memindahkan+%', true) like(result._key, 'memindahkan+%', true)
like(result._key, '+memindahkan%', true) ) && ( like(result._key, '%+aplikasi+%', true) like(result._key, 'aplikasi+%', true)
like(result._key, '+aplikasi%', true) ) && ( like(result._key, '%+ke+%', true) like(result._key, 'ke+%', true)
like(result._key, '+ke%', true) ) && ( like(result._key, '%+sd+%', true) like(result._key, 'sd+%', true)
like(result._key, '+sd%', true) ) && ( like(result._key, '%+tanpa+%', true) like(result._key, 'tanpa+%', true)
like(result._key, '+tanpa%', true) ) && ( like(result._key, '%+root+%', true) like(result._key, 'root+%', true)
like(result._key, '+root%', true) ) && ( like(result._key, '%+untuk+%', true) like(result._key, 'untuk+%', true)
like(result._key, '+untuk%', true) ) && ( like(result._key, '%+hp+%', true) like(result._key, 'hp+%', true)
like(result._key, '+hp%', true) ) && ( like(result._key, '%+lenovo+%', true) like(result._key, 'lenovo+%', true)

like(result._key, '+lenovo%', true) ) && ( like(result._key, '%+a3%', true) || like(result._key, 'a3%', true) ) && result.result != 0 && result.weight_alltime >= 3 SORT result.weight_alltime desc LIMIT 10 RETURN result`

Any suggestion? Or may be, is there any configuration that i can make to stop if the query taking too long?

jsteemann commented 7 years ago

Which version of ArangoDB are you using?

mhseptiadi commented 7 years ago

Currently im using ArangoDB 3.1.3

mhseptiadi commented 7 years ago

My coworker change the query into FOR result IN words FILTER (LIKE(CONCAT('+', result._key, '+'), '%+cara+%') && LIKE(CONCAT('+', result._key, '+'), '%+memindahkan+%') && LIKE(CONCAT('+', result._key, '+'), '%+aplikasi+%') && LIKE(CONCAT('+', result._key, '+'), '%+ke+%') && LIKE(CONCAT('+', result._key, '+'), '%+sd+%') && LIKE(CONCAT('+', result._key, '+'), '%+tanpa+%') && LIKE(CONCAT('+', result._key, '+'), '%+root+%') && LIKE(CONCAT('+', result._key, '+'), '%+untuk+%') && LIKE(CONCAT('+', result._key, '+'), '%+hp+%') && LIKE(CONCAT('+', result._key, '+'), '%+lenovo+%') && LIKE(CONCAT('+', result._key, '+'), '%+a3%')) && result.result != 0 && result.weight_alltime >= 3 SORT result.weight_alltime desc LIMIT 10 RETURN result

It reduces the load significantly and somehow it solve my problems. However, I still haven't found a way to stop a query if it takes too long.

jsteemann commented 7 years ago

It seems that query plan optimization takes too long for the first query. Looking into it...

jsteemann commented 7 years ago

The reason for the first query being slower than the second is that the first query contains nested logical conditions and the second does not (all logical conditions are on the top level). This makes a difference in the query optimizer's implementation, though from the user perspective it should not make a difference and the first query is expected to be fast as well.

Most execution time is spent during query plan optimization in Condition::transformNode, which recursively transforms the filter condition into disjunctive normal form (DNF). This takes too long, so it's a (server-side) bug.

frankmayer commented 7 years ago

@jsteemann has the server-side bug been registered/resolved? Can this be closed, then?

jsteemann commented 7 years ago

The issue has not been fixed yet on the server-side. I have created https://github.com/arangodb/arangodb/issues/2277 so it does not get off our radar. Thanks for reminding me.

This issue (php #204) can be closed.

razvanphp commented 7 years ago

However, I still haven't found a way to stop a query if it takes too long.

Regarding this side-question, you can actually use the Tools \ Query Management dropdown in the web interface to see the current running queries & kill them.

Another way is to use arangosh and do some tricks like:

var q = require("org/arangodb/aql/queries");
q.current().forEach(function(query) {    if (query.query.match(/postsToDelete/)) {      print("suspicious query: ", query);      q.kill(query.id);   }  });

.. to match on some part of AQL, or simply q.current().

mhseptiadi commented 7 years ago

@jsteemann already wrote https://www.arangodb.com/2016/01/killing-long-running-query/ similar to @razvanphp suggestion.

Filtering query.runTime with more than a specific time seems a good answers for my problems. Thanks guys.