Repository: ignite Updated Branches: refs/heads/master ed05d31fe -> 4ef96dd75
IGNITE-8568 Web Console: Added support for "Collocated" query mode on "Queries" screen. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4ef96dd7 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4ef96dd7 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4ef96dd7 Branch: refs/heads/master Commit: 4ef96dd758bd46ad19dc69d8b28bc4ddd2d081c7 Parents: ed05d31 Author: Vasiliy Sisko <[email protected]> Authored: Wed May 30 16:53:32 2018 +0700 Committer: Alexey Kuznetsov <[email protected]> Committed: Wed May 30 16:53:32 2018 +0700 ---------------------------------------------------------------------- modules/web-console/backend/app/schemas.js | 3 ++- .../components/queries-notebook/controller.js | 23 +++++++++++++++----- .../queries-notebook/template.tpl.pug | 8 +++++++ .../queries-notebooks-list/controller.js | 8 +++---- .../app/modules/agent/AgentManager.service.js | 20 +++++++++++------ 5 files changed, 45 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/4ef96dd7/modules/web-console/backend/app/schemas.js ---------------------------------------------------------------------- diff --git a/modules/web-console/backend/app/schemas.js b/modules/web-console/backend/app/schemas.js index 3f37487..5898ed8 100644 --- a/modules/web-console/backend/app/schemas.js +++ b/modules/web-console/backend/app/schemas.js @@ -1138,7 +1138,8 @@ module.exports.factory = function(mongoose) { qryType: String, nonCollocatedJoins: {type: Boolean, default: false}, enforceJoinOrder: {type: Boolean, default: false}, - lazy: {type: Boolean, default: false} + lazy: {type: Boolean, default: false}, + collocated: Boolean }] }); http://git-wip-us.apache.org/repos/asf/ignite/blob/4ef96dd7/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js b/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js index 6118afa..d5996e3 100644 --- a/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js +++ b/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js @@ -41,6 +41,8 @@ const ROW_IDX = {value: -2, type: 'java.lang.Integer', label: 'ROW_IDX'}; const NON_COLLOCATED_JOINS_SINCE = '1.7.0'; +const COLLOCATED_QUERY_SINCE = [['2.3.5', '2.4.0'], ['2.4.6', '2.5.0'], '2.5.2']; + const ENFORCE_JOIN_SINCE = [['1.7.9', '1.8.0'], ['1.8.4', '1.9.0'], '1.9.1']; const LAZY_QUERY_SINCE = [['2.1.4-p1', '2.2.0'], '2.2.1']; @@ -1406,7 +1408,7 @@ export class NotebookCtrl { .then(() => _closeOldQuery(paragraph)) .then(() => args.localNid || _chooseNode(args.cacheName, false)) .then((nid) => agentMgr.querySql(nid, args.cacheName, args.query, args.nonCollocatedJoins, - args.enforceJoinOrder, false, !!args.localNid, args.pageSize, args.lazy)) + args.enforceJoinOrder, false, !!args.localNid, args.pageSize, args.lazy, args.collocated)) .then((res) => _processQueryResult(paragraph, false, res)) .catch((err) => paragraph.setError(err)); }; @@ -1439,6 +1441,15 @@ export class NotebookCtrl { return false; }; + $scope.collocatedJoinsAvailable = (paragraph) => { + const cache = _.find($scope.caches, {name: paragraph.cacheName}); + + if (cache) + return !!_.find(cache.nodes, (node) => Version.since(node.version, ...COLLOCATED_QUERY_SINCE)); + + return false; + }; + $scope.enforceJoinOrderAvailable = (paragraph) => { const cache = _.find($scope.caches, {name: paragraph.cacheName}); @@ -1474,6 +1485,7 @@ export class NotebookCtrl { const nonCollocatedJoins = !!paragraph.nonCollocatedJoins; const enforceJoinOrder = !!paragraph.enforceJoinOrder; const lazy = !!paragraph.lazy; + const collocated = !!paragraph.collocated; $scope.queryAvailable(paragraph) && _chooseNode(paragraph.cacheName, local) .then((nid) => { @@ -1499,14 +1511,15 @@ export class NotebookCtrl { nonCollocatedJoins, enforceJoinOrder, localNid: local ? nid : null, - lazy + lazy, + collocated }; ActivitiesData.post({ action: '/queries/execute' }); const qry = args.maxPages ? addLimit(args.query, args.pageSize * args.maxPages) : query; - return agentMgr.querySql(nid, args.cacheName, qry, nonCollocatedJoins, enforceJoinOrder, false, local, args.pageSize, lazy); + return agentMgr.querySql(nid, args.cacheName, qry, nonCollocatedJoins, enforceJoinOrder, false, local, args.pageSize, lazy, collocated); }) .then((res) => { _processQueryResult(paragraph, true, res); @@ -1559,7 +1572,7 @@ export class NotebookCtrl { ActivitiesData.post({ action: '/queries/explain' }); - return agentMgr.querySql(nid, args.cacheName, args.query, false, !!paragraph.enforceJoinOrder, false, false, args.pageSize, false); + return agentMgr.querySql(nid, args.cacheName, args.query, args.nonCollocatedJoins, !!paragraph.enforceJoinOrder, false, false, args.pageSize, false, args.collocated); }) .then((res) => _processQueryResult(paragraph, true, res)) .catch((err) => { @@ -1753,7 +1766,7 @@ export class NotebookCtrl { return Promise.resolve(args.localNid || _chooseNode(args.cacheName, false)) .then((nid) => args.type === 'SCAN' ? agentMgr.queryScanGetAll(nid, args.cacheName, args.query, !!args.regEx, !!args.caseSensitive, !!args.near, !!args.localNid) - : agentMgr.querySqlGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.enforceJoinOrder, false, !!args.localNid, !!args.lazy)) + : agentMgr.querySqlGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.enforceJoinOrder, false, !!args.localNid, !!args.lazy, !!args.collocated)) .then((res) => _export(exportFileName(paragraph, true), paragraph.gridOptions.columnDefs, res.columns, res.rows)) .catch(Messages.showError) .then(() => { http://git-wip-us.apache.org/repos/asf/ignite/blob/4ef96dd7/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/template.tpl.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/template.tpl.pug b/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/template.tpl.pug index 60e0335..3ccf440 100644 --- a/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/template.tpl.pug +++ b/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/template.tpl.pug @@ -117,6 +117,14 @@ mixin query-settings <b>NOTE</b>: In some cases it may consume more heap memory or may take a long time than collocated joins.' data-trigger='hover') input(type='checkbox' ng-model='paragraph.nonCollocatedJoins') span Allow non-collocated joins + .row(ng-if='collocatedJoinsAvailable(paragraph)') + label.tipLabel(bs-tooltip data-placement='bottom' data-title='Used For Optimization Purposes Of Queries With GROUP BY Statements.<br/>\ + <b>NOTE:</b> Whenever Ignite executes a distributed query, it sends sub-queries to individual cluster members.<br/>\ + If you know in advance that the elements of your query selection are collocated together on the same node\ + and you group by collocated key (primary or affinity key), then Ignite can make significant performance and\ + network optimizations by grouping data on remote nodes.' data-trigger='hover') + input(type='checkbox' ng-model='paragraph.collocated') + span Collocated Query .row(ng-if='enforceJoinOrderAvailable(paragraph)') label.tipLabel(bs-tooltip data-placement='bottom' data-title='Enforce join order of tables in the query.<br/>\ If <b>set</b>, then query optimizer will not reorder tables within join.<br/>\ http://git-wip-us.apache.org/repos/asf/ignite/blob/4ef96dd7/modules/web-console/frontend/app/components/page-queries/components/queries-notebooks-list/controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-queries/components/queries-notebooks-list/controller.js b/modules/web-console/frontend/app/components/page-queries/components/queries-notebooks-list/controller.js index 2e4146c..ad86a10 100644 --- a/modules/web-console/frontend/app/components/page-queries/components/queries-notebooks-list/controller.js +++ b/modules/web-console/frontend/app/components/page-queries/components/queries-notebooks-list/controller.js @@ -33,14 +33,14 @@ export class NotebooksListCtrl { const categories = [ { name: 'Name', visible: true, enableHiding: false }, - { name: 'SQL Query', visible: true, enableHiding: false }, - { name: 'Scan Query', visible: true, enableHiding: false } + { name: 'SQL Queries', visible: true, enableHiding: false }, + { name: 'Scan Queries', visible: true, enableHiding: false } ]; const columnDefs = [ { name: 'name', displayName: 'Notebook name', categoryDisplayName: 'Name', field: 'name', cellTemplate: notebookNameTemplate, pinnedLeft: true, filter: { placeholder: 'Filter by Name...' } }, - { name: 'sqlQueryNum', displayName: 'SQL Query', categoryDisplayName: 'SQL Query', field: 'sqlQueriesParagraphsLength', cellTemplate: sqlQueryTemplate, enableSorting: true, type: 'number', minWidth: 150, width: 150, enableFiltering: false }, - { name: 'scanQueryNum', displayName: 'Scan Query', categoryDisplayName: 'Scan Query', field: 'scanQueriesParagraphsLength', cellTemplate: scanQueryTemplate, enableSorting: true, type: 'number', minWidth: 150, width: 150, enableFiltering: false } + { name: 'sqlQueryNum', displayName: 'SQL Queries', categoryDisplayName: 'SQL Queries', field: 'sqlQueriesParagraphsLength', cellTemplate: sqlQueryTemplate, enableSorting: true, type: 'number', minWidth: 150, width: 150, enableFiltering: false }, + { name: 'scanQueryNum', displayName: 'Scan Queries', categoryDisplayName: 'Scan Queries', field: 'scanQueriesParagraphsLength', cellTemplate: scanQueryTemplate, enableSorting: true, type: 'number', minWidth: 150, width: 150, enableFiltering: false } ]; this.gridOptions = { http://git-wip-us.apache.org/repos/asf/ignite/blob/4ef96dd7/modules/web-console/frontend/app/modules/agent/AgentManager.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js index b73b2c1..fd44f9e 100644 --- a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js +++ b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js @@ -32,6 +32,7 @@ const State = { }; const LAZY_QUERY_SINCE = [['2.1.4-p1', '2.2.0'], '2.2.1']; +const COLLOCATED_QUERY_SINCE = [['2.3.5', '2.4.0'], ['2.4.6', '2.5.0'], '2.5.2']; class ConnectionState { constructor(cluster) { @@ -557,15 +558,19 @@ export default class IgniteAgentManager { * @param {Boolean} local Flag whether to execute query locally. * @param {int} pageSz * @param {Boolean} lazy query flag. + * @param {Boolean} collocated Collocated query. * @returns {Promise} */ - querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy) { + querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy, collocated) { if (this.available('2.0.0')) { - const task = this.available(...LAZY_QUERY_SINCE) ? - this.visorTask('querySqlX2', nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy) : - this.visorTask('querySqlX2', nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz); + let args = [cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz]; - return task.then(({error, result}) => { + if (this.available(COLLOCATED_QUERY_SINCE)) + args = [...args, lazy, collocated]; + else if (this.available(...LAZY_QUERY_SINCE)) + args = [...args, lazy]; + + return this.visorTask('querySqlX2', nid, ...args).then(({error, result}) => { if (_.isEmpty(error)) return result; @@ -615,9 +620,10 @@ export default class IgniteAgentManager { * @param {Boolean} replicatedOnly Flag whether query contains only replicated tables. * @param {Boolean} local Flag whether to execute query locally. * @param {Boolean} lazy query flag. + * @param {Boolean} collocated Collocated query. * @returns {Promise} */ - querySqlGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, lazy) { + querySqlGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, lazy, collocated) { // Page size for query. const pageSz = 1024; @@ -635,7 +641,7 @@ export default class IgniteAgentManager { }); }; - return this.querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy) + return this.querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz, lazy, collocated) .then(fetchResult); }
