This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 26d2ec4e000 IGNITE-27410 SQL Calcite: Refactor JmhSqlBenchmark - Fixes 
#12594.
26d2ec4e000 is described below

commit 26d2ec4e000fb45560da5e63b6a2c8549b4e0fd9
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Fri Jan 23 12:06:05 2026 +0300

    IGNITE-27410 SQL Calcite: Refactor JmhSqlBenchmark - Fixes #12594.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../jmh/sql/JmhSqlAbstractBenchmark.java           | 180 +++++++++++
 .../benchmarks/jmh/sql/JmhSqlAggBenchmark.java     |  78 +++++
 .../benchmarks/jmh/sql/JmhSqlBenchmark.java        | 355 ---------------------
 .../jmh/sql/JmhSqlCorrelateBenchmark.java          |  61 ++++
 .../benchmarks/jmh/sql/JmhSqlDmlBenchmark.java     | 128 ++++++++
 .../jmh/sql/JmhSqlDmlReplicatedBenchmark.java      |  50 +++
 .../benchmarks/jmh/sql/JmhSqlJoinBenchmark.java    |  85 +++++
 .../benchmarks/jmh/sql/JmhSqlScanBenchmark.java    |  96 ++++++
 .../jmh/sql/JmhSqlScanReplicatedBenchmark.java     |  50 +++
 .../benchmarks/jmh/sql/JmhSqlSetOpBenchmark.java   |  80 +++++
 .../benchmarks/jmh/sql/JmhSqlSortBenchmark.java    |  79 +++++
 .../benchmarks/jmh/sql/JmhSqlUdfBenchmark.java     |  81 +++++
 12 files changed, 968 insertions(+), 355 deletions(-)

diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlAbstractBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlAbstractBenchmark.java
new file mode 100644
index 00000000000..c30f61dc102
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlAbstractBenchmark.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.calcite.CalciteQueryEngineConfiguration;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.SqlConfiguration;
+import org.apache.ignite.indexing.IndexingQueryEngineConfiguration;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Abstract SQL queries benchmark.
+ */
+@Fork(1)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+@Warmup(iterations = 3, time = 5)
+@Measurement(iterations = 3, time = 5)
+@State(Scope.Benchmark)
+public abstract class JmhSqlAbstractBenchmark {
+    /** Count of server nodes. */
+    protected static final int SRV_NODES_CNT = 3;
+
+    /** Keys count. */
+    protected static final int KEYS_CNT = 100000;
+
+    /** Size of batch. */
+    protected static final int BATCH_SIZE = 1000;
+
+    /** Partitions count. */
+    protected static final int PARTS_CNT = 1024;
+
+    /** IP finder shared across nodes. */
+    private static final TcpDiscoveryVmIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** Query engine. */
+    @Param({"H2", "CALCITE"})
+    protected String engine;
+
+    /** Ignite client. */
+    protected Ignite client;
+
+    /** Servers. */
+    protected final Ignite[] servers = new Ignite[SRV_NODES_CNT];
+
+    /** Cache. */
+    private IgniteCache<Integer, Item> cache;
+
+    /**
+     * Create Ignite configuration.
+     *
+     * @param igniteInstanceName Ignite instance name.
+     * @return Configuration.
+     */
+    protected IgniteConfiguration configuration(String igniteInstanceName) {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setIgniteInstanceName(igniteInstanceName);
+        cfg.setLocalHost("127.0.0.1");
+        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER));
+        cfg.setSqlConfiguration(new 
SqlConfiguration().setQueryEnginesConfiguration(
+            "CALCITE".equals(engine) ? new CalciteQueryEngineConfiguration() : 
new IndexingQueryEngineConfiguration()
+        ));
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache configuration.
+     */
+    protected CacheConfiguration<Integer, Item> cacheConfiguration() {
+        return new CacheConfiguration<Integer, Item>("CACHE")
+            .setIndexedTypes(Integer.class, Item.class)
+            .setAffinity(new RendezvousAffinityFunction(false, PARTS_CNT));
+    }
+
+    /**
+     * Initiate Ignite and caches.
+     */
+    @Setup(Level.Trial)
+    public void setup() {
+        for (int i = 0; i < SRV_NODES_CNT; i++)
+            servers[i] = Ignition.start(configuration("server" + i));
+
+        client = Ignition.start(configuration("client").setClientMode(true));
+
+        cache = client.getOrCreateCache(cacheConfiguration());
+
+        try (IgniteDataStreamer<Integer, Item> ds = 
client.dataStreamer("CACHE")) {
+            for (int i = 0; i < KEYS_CNT; i++)
+                ds.addData(i, new Item(i));
+        }
+    }
+
+    /**
+     * Stop Ignite instance.
+     */
+    @TearDown
+    public void tearDown() {
+        client.close();
+
+        for (Ignite ignite : servers)
+            ignite.close();
+    }
+
+    /** */
+    protected List<List<?>> executeSql(String sql, Object... args) {
+        return cache.query(new SqlFieldsQuery(sql).setArgs(args)).getAll();
+    }
+
+    /** */
+    protected static class Item {
+        /** */
+        @QuerySqlField
+        private final String name;
+
+        /** */
+        @QuerySqlField
+        private final int fld;
+
+        /** */
+        @QuerySqlField
+        private final int fldBatch;
+
+        /** */
+        @QuerySqlField(index = true)
+        private final int fldIdx;
+
+        /** */
+        @QuerySqlField(index = true)
+        private final int fldIdxBatch;
+
+        /** */
+        public Item(int val) {
+            name = "name" + val;
+            fld = val;
+            fldBatch = val / BATCH_SIZE;
+            fldIdx = val;
+            fldIdxBatch = val / BATCH_SIZE;
+        }
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlAggBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlAggBenchmark.java
new file mode 100644
index 00000000000..e767c1936de
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlAggBenchmark.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark aggregate SQL queries.
+ */
+public class JmhSqlAggBenchmark extends JmhSqlAbstractBenchmark {
+    /**
+     * Query with group by and aggregate.
+     */
+    @Benchmark
+    public void queryGroupBy() {
+        List<?> res = executeSql("SELECT fldBatch, AVG(fld) FROM Item GROUP BY 
fldBatch");
+
+        if (res.size() != KEYS_CNT / BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query with indexed field group by and aggregate.
+     */
+    @Benchmark
+    public void queryGroupByIndexed() {
+        List<?> res = executeSql("SELECT fldIdxBatch, AVG(fld) FROM Item GROUP 
BY fldIdxBatch");
+
+        if (res.size() != KEYS_CNT / BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query sum of indexed field.
+     */
+    @Benchmark
+    public void querySumIndexed() {
+        List<List<?>> res = executeSql("SELECT sum(fldIdx) FROM Item");
+
+        Long expRes = ((long)KEYS_CNT) * (KEYS_CNT - 1) / 2;
+
+        if (!expRes.equals(res.get(0).get(0)))
+            throw new AssertionError("Unexpected result: " + res.get(0));
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlAggBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlBenchmark.java
deleted file mode 100644
index 0698fb93327..00000000000
--- 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlBenchmark.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.benchmarks.jmh.sql;
-
-import java.util.List;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.IgniteDataStreamer;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.calcite.CalciteQueryEngineConfiguration;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.configuration.SqlConfiguration;
-import org.apache.ignite.indexing.IndexingQueryEngineConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Fork;
-import org.openjdk.jmh.annotations.Level;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Param;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
-import org.openjdk.jmh.annotations.Warmup;
-import org.openjdk.jmh.runner.Runner;
-import org.openjdk.jmh.runner.options.Options;
-import org.openjdk.jmh.runner.options.OptionsBuilder;
-
-/**
- * Benchmark simple SQL queries.
- */
-@State(Scope.Benchmark)
-@Fork(1)
-@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.SECONDS)
-@Warmup(iterations = 3, time = 5)
-@Measurement(iterations = 3, time = 5)
-public class JmhSqlBenchmark {
-    /** Count of server nodes. */
-    private static final int SRV_NODES_CNT = 3;
-
-    /** Keys count. */
-    private static final int KEYS_CNT = 100000;
-
-    /** Size of batch. */
-    private static final int BATCH_SIZE = 1000;
-
-    /** Partitions count. */
-    private static final int PARTS_CNT = 1024;
-
-    /** IP finder shared across nodes. */
-    private static final TcpDiscoveryVmIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
-
-    /** Query engine. */
-    @Param({"H2", "CALCITE"})
-    private String engine;
-
-    /** Ignite client. */
-    private Ignite client;
-
-    /** Servers. */
-    private final Ignite[] servers = new Ignite[SRV_NODES_CNT];
-
-    /** Cache. */
-    private IgniteCache<Integer, Item> cache;
-
-    /**
-     * Create Ignite configuration.
-     *
-     * @param igniteInstanceName Ignite instance name.
-     * @return Configuration.
-     */
-    private IgniteConfiguration configuration(String igniteInstanceName) {
-        IgniteConfiguration cfg = new IgniteConfiguration();
-
-        cfg.setIgniteInstanceName(igniteInstanceName);
-        cfg.setLocalHost("127.0.0.1");
-        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER));
-        cfg.setSqlConfiguration(new 
SqlConfiguration().setQueryEnginesConfiguration(
-            "CALCITE".equals(engine) ? new CalciteQueryEngineConfiguration() : 
new IndexingQueryEngineConfiguration()
-        ));
-
-        return cfg;
-    }
-
-    /**
-     * Initiate Ignite and caches.
-     */
-    @Setup(Level.Trial)
-    public void setup() {
-        for (int i = 0; i < SRV_NODES_CNT; i++)
-            servers[i] = Ignition.start(configuration("server" + i));
-
-        client = Ignition.start(configuration("client").setClientMode(true));
-
-        cache = client.getOrCreateCache(new CacheConfiguration<Integer, 
Item>("CACHE")
-            .setIndexedTypes(Integer.class, Item.class)
-            .setAffinity(new RendezvousAffinityFunction(false, PARTS_CNT))
-        );
-
-        try (IgniteDataStreamer<Integer, Item> ds = 
client.dataStreamer("CACHE")) {
-            for (int i = 0; i < KEYS_CNT; i++)
-                ds.addData(i, new Item(i));
-        }
-    }
-
-    /**
-     * Stop Ignite instance.
-     */
-    @TearDown
-    public void tearDown() {
-        client.close();
-
-        for (Ignite ignite : servers)
-            ignite.close();
-    }
-
-    /**
-     * Query unique value (full scan).
-     */
-    @Benchmark
-    public void querySimpleUnique() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql("SELECT name FROM Item WHERE fld=?", key);
-
-        if (res.size() != 1)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query unique value (indexed).
-     */
-    @Benchmark
-    public void querySimpleUniqueIndexed() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql("SELECT name FROM Item WHERE fldIdx=?", key);
-
-        if (res.size() != 1)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query batch (full scan).
-     */
-    @Benchmark
-    public void querySimpleBatch() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql("SELECT name FROM Item WHERE fldBatch=?", key 
/ BATCH_SIZE);
-
-        if (res.size() != BATCH_SIZE)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query batch (indexed).
-     */
-    @Benchmark
-    public void querySimpleBatchIndexed() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql("SELECT name FROM Item WHERE fldIdxBatch=?", 
key / BATCH_SIZE);
-
-        if (res.size() != BATCH_SIZE)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query with group by and aggregate.
-     */
-    @Benchmark
-    public void queryGroupBy() {
-        List<?> res = executeSql("SELECT fldBatch, AVG(fld) FROM Item GROUP BY 
fldBatch");
-
-        if (res.size() != KEYS_CNT / BATCH_SIZE)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query with indexed field group by and aggregate.
-     */
-    @Benchmark
-    public void queryGroupByIndexed() {
-        List<?> res = executeSql("SELECT fldIdxBatch, AVG(fld) FROM Item GROUP 
BY fldIdxBatch");
-
-        if (res.size() != KEYS_CNT / BATCH_SIZE)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query with sorting (full set).
-     */
-    @Benchmark
-    public void queryOrderByFull() {
-        List<?> res = executeSql("SELECT name, fld FROM Item ORDER BY fld 
DESC");
-
-        if (res.size() != KEYS_CNT)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query with sorting (batch).
-     */
-    @Benchmark
-    public void queryOrderByBatch() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql("SELECT name, fld FROM Item WHERE 
fldIdxBatch=? ORDER BY fld DESC", key / BATCH_SIZE);
-
-        if (res.size() != BATCH_SIZE)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query sum of indexed field.
-     */
-    @Benchmark
-    public void querySumIndexed() {
-        List<List<?>> res = executeSql("SELECT sum(fldIdx) FROM Item");
-
-        Long expRes = ((long)KEYS_CNT) * (KEYS_CNT - 1) / 2;
-
-        if (!expRes.equals(res.get(0).get(0)))
-            throw new AssertionError("Unexpected result: " + res.get(0));
-    }
-
-    /**
-     * Query with EXCEPT set op.
-     */
-    @Benchmark
-    public void queryExcept() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql(
-            "SELECT fld, fldIdx, fldBatch, fldIdxBatch FROM Item WHERE 
fldIdxBatch=? " +
-                "EXCEPT " +
-                "SELECT fld + ?, fldIdx + ?, fldBatch, fldIdxBatch FROM Item 
WHERE fldIdxBatch=?",
-            key / BATCH_SIZE, BATCH_SIZE / 2, BATCH_SIZE / 2, key / 
BATCH_SIZE);
-
-        if (res.size() != BATCH_SIZE / 2)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query with INTERSECT set op.
-     */
-    @Benchmark
-    public void queryIntersect() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql(
-            "SELECT fld, fldIdx, fldBatch, fldIdxBatch FROM Item WHERE 
fldIdxBatch=? " +
-                "INTERSECT " +
-                "SELECT fld + ?, fldIdx + ?, fldBatch, fldIdxBatch FROM Item 
WHERE fldIdxBatch=?",
-            key / BATCH_SIZE, BATCH_SIZE / 2, BATCH_SIZE / 2, key / 
BATCH_SIZE);
-
-        if (res.size() != BATCH_SIZE / 2)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /**
-     * Query with correlated subquery.
-     */
-    @Benchmark
-    public void queryCorrelated() {
-        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
-
-        List<?> res = executeSql(
-            "SELECT fld FROM Item i0 WHERE fldIdxBatch=? AND EXISTS " +
-                "(SELECT 1 FROM Item i1 WHERE i0.fld = i1.fld + ? AND 
i0.fldBatch = i1.fldBatch)",
-            key / BATCH_SIZE, BATCH_SIZE / 2);
-
-        // Skip result check for H2 engine, because query can't be executed 
correctly on H2.
-        if (!"H2".equals(engine) && res.size() != BATCH_SIZE / 2)
-            throw new AssertionError("Unexpected result size: " + res.size());
-    }
-
-    /** */
-    private List<List<?>> executeSql(String sql, Object... args) {
-        return cache.query(new SqlFieldsQuery(sql).setArgs(args)).getAll();
-    }
-
-    /**
-     * Run benchmarks.
-     *
-     * @param args Args.
-     * @throws Exception Exception.
-     */
-    public static void main(String[] args) throws Exception {
-        final Options options = new OptionsBuilder()
-            .include(JmhSqlBenchmark.class.getSimpleName())
-            .build();
-
-        new Runner(options).run();
-    }
-
-    /** */
-    private static class Item {
-        /** */
-        @QuerySqlField
-        private final String name;
-
-        /** */
-        @QuerySqlField
-        private final int fld;
-
-        /** */
-        @QuerySqlField
-        private final int fldBatch;
-
-        /** */
-        @QuerySqlField(index = true)
-        private final int fldIdx;
-
-        /** */
-        @QuerySqlField(index = true)
-        private final int fldIdxBatch;
-
-        /** */
-        public Item(int val) {
-            name = "name" + val;
-            fld = val;
-            fldBatch = val / BATCH_SIZE;
-            fldIdx = val;
-            fldIdxBatch = val / BATCH_SIZE;
-        }
-    }
-}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlCorrelateBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlCorrelateBenchmark.java
new file mode 100644
index 00000000000..07004ae63ee
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlCorrelateBenchmark.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark correlated SQL queries.
+ */
+public class JmhSqlCorrelateBenchmark extends JmhSqlAbstractBenchmark {
+    /**
+     * Query with correlated subquery.
+     */
+    @Benchmark
+    public void queryCorrelated() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql(
+            "SELECT fld FROM Item i0 WHERE fldIdxBatch=? AND EXISTS " +
+                "(SELECT 1 FROM Item i1 WHERE i0.fld = i1.fld + ? AND 
i0.fldBatch = i1.fldBatch)",
+            key / BATCH_SIZE, BATCH_SIZE / 2);
+
+        // Skip result check for H2 engine, because query can't be executed 
correctly on H2.
+        if (!"H2".equals(engine) && res.size() != BATCH_SIZE / 2)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlCorrelateBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlDmlBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlDmlBenchmark.java
new file mode 100644
index 00000000000..6cdb00ff48e
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlDmlBenchmark.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import org.apache.ignite.IgniteDataStreamer;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark DML queries.
+ */
+public class JmhSqlDmlBenchmark extends JmhSqlAbstractBenchmark {
+    /**
+     * Initiate new cache.
+     */
+    @Override public void setup() {
+        super.setup();
+
+        
client.getOrCreateCache(cacheConfiguration().setName("CACHE2").setSqlSchema("CACHE2"));
+
+        try (IgniteDataStreamer<Integer, Item> ds = 
client.dataStreamer("CACHE2")) {
+            for (int i = 0; i < KEYS_CNT; i++)
+                ds.addData(i, new Item(i));
+        }
+    }
+
+    /**
+     * INSERT/DELETE batched.
+     */
+    @Benchmark
+    public void insertDeleteBatch() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<List<?>> res = executeSql("INSERT INTO CACHE2.Item (_key, name, 
fld, fldBatch, fldIdx, fldIdxBatch) " +
+                "SELECT _key + ?, name, fld, fldBatch, fldIdx, fldIdxBatch + ? 
FROM CACHE.Item WHERE fldIdxBatch=?",
+            KEYS_CNT, KEYS_CNT, key / BATCH_SIZE);
+
+        checkUpdatedCount(res, BATCH_SIZE);
+
+        res = executeSql("DELETE FROM CACHE2.Item WHERE fldIdxBatch=?",
+            KEYS_CNT + key / BATCH_SIZE);
+
+        checkUpdatedCount(res, BATCH_SIZE);
+    }
+
+    /**
+     * INSERT/DELETE single key.
+     */
+    @Benchmark
+    public void insertDeleteUniqueIndexed() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<List<?>> res = executeSql("INSERT INTO CACHE2.Item (_key, name, 
fld, fldBatch, fldIdx, fldIdxBatch) " +
+                "VALUES (?, 'name', 0, 0, ?, 0)",
+            KEYS_CNT + key, KEYS_CNT + key);
+
+        checkUpdatedCount(res, 1);
+
+        res = executeSql("DELETE FROM CACHE2.Item WHERE fldIdx=?", KEYS_CNT + 
key);
+
+        checkUpdatedCount(res, 1);
+    }
+
+    /**
+     * UPDATE batched.
+     */
+    @Benchmark
+    public void updateBatch() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<List<?>> res = executeSql("UPDATE CACHE2.Item SET fld = fld + 1 
WHERE fldIdxBatch=?", key / BATCH_SIZE);
+
+        checkUpdatedCount(res, BATCH_SIZE);
+    }
+
+    /**
+     * UPDATE single key.
+     */
+    @Benchmark
+    public void updateUniqueIndexed() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<List<?>> res = executeSql("UPDATE CACHE2.Item SET fld = fld + 1 
WHERE fldIdx=?", key);
+
+        checkUpdatedCount(res, 1);
+    }
+
+    /** */
+    private void checkUpdatedCount(List<List<?>> res, int expCnt) {
+        if (res.size() != 1 || (Long)res.get(0).get(0) != expCnt) {
+            throw new AssertionError("Unexpected " + (res.size() != 1 ? 
"result size: " + res.size()
+                : "updated entries count: " + res.get(0).get(0)));
+        }
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlDmlBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlDmlReplicatedBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlDmlReplicatedBenchmark.java
new file mode 100644
index 00000000000..eb0407d2ee4
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlDmlReplicatedBenchmark.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark DML queries on replicated cache.
+ */
+public class JmhSqlDmlReplicatedBenchmark extends JmhSqlDmlBenchmark {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration<Integer, Item> cacheConfiguration() 
{
+        return super.cacheConfiguration().setCacheMode(CacheMode.REPLICATED)
+            
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlDmlReplicatedBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlJoinBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlJoinBenchmark.java
new file mode 100644
index 00000000000..611e6ff2947
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlJoinBenchmark.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark JOIN queries.
+ */
+public class JmhSqlJoinBenchmark extends JmhSqlAbstractBenchmark {
+    /** Count of entries in DEPT table. */
+    protected static final int DEPT_CNT = 1_000;
+
+    /** Count of entries in EMP table. */
+    protected static final int EMP_CNT = 10_000;
+
+    /**
+     * Initiate new tables.
+     */
+    @Override public void setup() {
+        super.setup();
+
+        executeSql("CREATE TABLE emp(empid INTEGER, deptid INTEGER, name 
VARCHAR, salary INTEGER, " +
+            "PRIMARY KEY(empid, deptid)) WITH \"AFFINITY_KEY=deptid\"");
+        executeSql("CREATE TABLE dept(deptid INTEGER, name VARCHAR, addr 
VARCHAR, PRIMARY KEY(deptid))");
+
+        for (int i = 0; i < DEPT_CNT; i++) {
+            executeSql("INSERT INTO dept(deptid, name, addr) VALUES (?, ?, ?)",
+                i, "Department " + i, "Address " + i);
+        }
+
+        for (int i = 0; i < EMP_CNT; i++) {
+            executeSql("INSERT INTO emp (empid, deptid, name, salary) VALUES 
(?, ?, ?, ?)",
+                i, i % DEPT_CNT, "Employee " + i, i / BATCH_SIZE);
+        }
+    }
+
+    /**
+     * Colocated distributed join.
+     */
+    @Benchmark
+    public void colocatedDistributedJoin() {
+        int key = ThreadLocalRandom.current().nextInt(EMP_CNT / BATCH_SIZE);
+
+        List<List<?>> res = executeSql("SELECT emp.name, dept.name FROM emp 
JOIN dept ON emp.deptid = dept.deptid " +
+                "WHERE emp.salary = ?", key);
+
+        if (res.size() != BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlJoinBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlScanBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlScanBenchmark.java
new file mode 100644
index 00000000000..42080465b80
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlScanBenchmark.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark scan SQL queries.
+ */
+public class JmhSqlScanBenchmark extends JmhSqlAbstractBenchmark {
+    /**
+     * Query unique value (full scan).
+     */
+    @Benchmark
+    public void scanUnique() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql("SELECT name FROM Item WHERE fld=?", key);
+
+        if (res.size() != 1)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query unique value (indexed).
+     */
+    @Benchmark
+    public void scanUniqueIndexed() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql("SELECT name FROM Item WHERE fldIdx=?", key);
+
+        if (res.size() != 1)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query batch (full scan).
+     */
+    @Benchmark
+    public void scanBatch() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql("SELECT name FROM Item WHERE fldBatch=?", key 
/ BATCH_SIZE);
+
+        if (res.size() != BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query batch (indexed).
+     */
+    @Benchmark
+    public void scanBatchIndexed() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql("SELECT name FROM Item WHERE fldIdxBatch=?", 
key / BATCH_SIZE);
+
+        if (res.size() != BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlScanBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlScanReplicatedBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlScanReplicatedBenchmark.java
new file mode 100644
index 00000000000..9832bbe6dc6
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlScanReplicatedBenchmark.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark replicated scan SQL queries.
+ */
+public class JmhSqlScanReplicatedBenchmark extends JmhSqlScanBenchmark {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration<Integer, Item> cacheConfiguration() 
{
+        return super.cacheConfiguration().setCacheMode(CacheMode.REPLICATED)
+            .setAffinity(new RendezvousAffinityFunction().setPartitions(100)); 
// Return to default for replicated.
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlScanReplicatedBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlSetOpBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlSetOpBenchmark.java
new file mode 100644
index 00000000000..09f8891218b
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlSetOpBenchmark.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.profile.GCProfiler;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark set op SQL queries.
+ */
+public class JmhSqlSetOpBenchmark extends JmhSqlAbstractBenchmark {
+    /**
+     * Query with EXCEPT set op.
+     */
+    @Benchmark
+    public void queryExcept() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql(
+            "SELECT fld, fldIdx, fldBatch, fldIdxBatch FROM Item WHERE 
fldIdxBatch=? " +
+                "EXCEPT " +
+                "SELECT fld + ?, fldIdx + ?, fldBatch, fldIdxBatch FROM Item 
WHERE fldIdxBatch=?",
+            key / BATCH_SIZE, BATCH_SIZE / 2, BATCH_SIZE / 2, key / 
BATCH_SIZE);
+
+        if (res.size() != BATCH_SIZE / 2)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query with INTERSECT set op.
+     */
+    @Benchmark
+    public void queryIntersect() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql(
+            "SELECT fld, fldIdx, fldBatch, fldIdxBatch FROM Item WHERE 
fldIdxBatch=? " +
+                "INTERSECT " +
+                "SELECT fld + ?, fldIdx + ?, fldBatch, fldIdxBatch FROM Item 
WHERE fldIdxBatch=?",
+            key / BATCH_SIZE, BATCH_SIZE / 2, BATCH_SIZE / 2, key / 
BATCH_SIZE);
+
+        if (res.size() != BATCH_SIZE / 2)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlSetOpBenchmark.class.getSimpleName())
+            .addProfiler(GCProfiler.class)
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlSortBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlSortBenchmark.java
new file mode 100644
index 00000000000..8493a2a9138
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlSortBenchmark.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark sort SQL queries.
+ */
+public class JmhSqlSortBenchmark extends JmhSqlAbstractBenchmark {
+    /**
+     * Query with sorting (full set).
+     */
+    @Benchmark
+    public void queryOrderByFull() {
+        List<?> res = executeSql("SELECT name, fld FROM Item ORDER BY fld 
DESC");
+
+        if (res.size() != KEYS_CNT)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query with sorting (batch).
+     */
+    @Benchmark
+    public void queryOrderByBatch() {
+        int key = ThreadLocalRandom.current().nextInt(KEYS_CNT);
+
+        List<?> res = executeSql("SELECT name, fld FROM Item WHERE 
fldIdxBatch=? ORDER BY fld DESC", key / BATCH_SIZE);
+
+        if (res.size() != BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query with sorting (with limit).
+     */
+    @Benchmark
+    public void queryOrderByWithLimit() {
+        List<?> res = executeSql("SELECT name, fld FROM Item ORDER BY fld DESC 
LIMIT " + BATCH_SIZE);
+
+        if (res.size() != BATCH_SIZE)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlSortBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}
diff --git 
a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlUdfBenchmark.java
 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlUdfBenchmark.java
new file mode 100644
index 00000000000..c3d24ca055b
--- /dev/null
+++ 
b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/sql/JmhSqlUdfBenchmark.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.benchmarks.jmh.sql;
+
+import java.util.List;
+import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark user defined functions in SQL queries.
+ */
+public class JmhSqlUdfBenchmark extends JmhSqlAbstractBenchmark {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration<Integer, Item> cacheConfiguration() 
{
+        return 
super.cacheConfiguration().setSqlFunctionClasses(FunctionsLibrary.class);
+    }
+
+    /** */
+    public static class FunctionsLibrary {
+        /** */
+        @QuerySqlFunction
+        public static int mul(int a, int b) {
+            return a * b;
+        }
+    }
+
+    /**
+     * Query with user defined functions executed on initiator node.
+     */
+    @Benchmark
+    public void queryFunctionsLocal() {
+        List<?> res = executeSql("SELECT mul(mul(x, x), mul(x, x)) FROM 
system_range(1, ?)", KEYS_CNT);
+
+        if (res.size() != KEYS_CNT)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Query with user defined functions executed on remote nodes.
+     */
+    @Benchmark
+    public void queryFunctionsRemote() {
+        List<?> res = executeSql("SELECT mul(mul(fld, fldIdx), mul(fldBatch, 
fldIdxBatch)) FROM Item");
+
+        if (res.size() != KEYS_CNT)
+            throw new AssertionError("Unexpected result size: " + res.size());
+    }
+
+    /**
+     * Run benchmarks.
+     *
+     * @param args Args.
+     * @throws Exception Exception.
+     */
+    public static void main(String[] args) throws Exception {
+        final Options options = new OptionsBuilder()
+            .include(JmhSqlUdfBenchmark.class.getSimpleName())
+            .build();
+
+        new Runner(options).run();
+    }
+}

Reply via email to