[ 
https://issues.apache.org/jira/browse/CASSANDRA-19497?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17895465#comment-17895465
 ] 

Caleb Rackliffe commented on CASSANDRA-19497:
---------------------------------------------

Did some local testing to prove the patch, as it now stands, buys us 
something...
{noformat}
import org.junit.Test;

import org.HdrHistogram.Histogram;
import org.apache.cassandra.index.sai.SAITester;

public class RowBatchingPerformanceTest extends SAITester
{
    @Test
    public void test() throws Throwable
    {
        createTable("CREATE TABLE %s (k int, c int, val int, PRIMARY KEY (k, 
c))");
        createIndex("CREATE INDEX ON %s(val) USING 'sai'");

        for (int i = 0; i < 10000; i++)
            execute("INSERT INTO %s (k, c, val) VALUES (0, ?, ?)", i, i);

        flush();

        Histogram histogram = new Histogram(4);

        for (int i = 0; i < 100000; i++)
        {
            long start = System.nanoTime();
            execute("SELECT k, c FROM %s WHERE k = 0 AND val > 9000");
            histogram.recordValue(System.nanoTime() - start);

            if (i % 10000 == 0)
            {
                System.err.println("50th: " + 
histogram.getValueAtPercentile(0.5));
                System.err.println("95th: " + 
histogram.getValueAtPercentile(0.95));
                System.err.println("99th: " + 
histogram.getValueAtPercentile(0.99));
            }
        }
    }
}
{noformat}

We create a table, throw an index on the one non-key column, and then populate 
a single partition w/ 10k rows. We then fire off 100k SAI queries, each looking 
for the last ~1000 rows of that partition. The query has no limit. (The data 
obviously fits in memory, but the results here give us a pretty good idea of 
how the CPU and allocation-related aspects of this codepath perform.)
|branch|p50 (nanos)|p99 (nanos)|
|trunk|7,558,143|7,578,111|
|patch w/ 100-row batches|1,209,919|1,220,223|

It's not that surprising that batching is 6x faster. Issuing 10 
{{SinglePartitionReadCommand}}s is better than issuing 1000. We might be able 
to improve things even more if we can find a way to avoid all the {{TreeSet}} 
building in {{QueryController#makeFilter()}}.

Given this is a nice improvement, I'd like to get some early review...

> ResultRetriever should batch clusterings/rows during SAI post-filtering reads
> -----------------------------------------------------------------------------
>
>                 Key: CASSANDRA-19497
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-19497
>             Project: Cassandra
>          Issue Type: Improvement
>          Components: Feature/SAI
>            Reporter: Caleb Rackliffe
>            Assignee: Caleb Rackliffe
>            Priority: Normal
>             Fix For: 5.0.x, 5.x
>
>         Attachments: alloc-trunk.html, cpu-trunk.html, heap-flamegraph.html, 
> wall-no-parked-threads.html
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> SAI currently creates and executes a {{SinglePartitionReadCommand}} for every 
> {{PrimaryKey}} the index produces to read the corresponding row for 
> post-filtering. Informed by the limits present in the read command itself, it 
> should be possible to batch those reads w/ a {{ClusteringIndexNamesFilter}} 
> in many fewer {{SinglePartitionReadCommands}}. When we have a handful of 
> matches in a large partition, this seems like would involve many fewer seeks, 
> less unnecessary object creation, etc.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to