<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/performance-differences-between-revoscaler-columnstore-table-and-in-memory-oltp-table/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://tomaztsql.wordpress.com/2017/04/28/performance-differences-between-revoscaler-columnstore-table-and-in-memory-oltp-table/"> R – TomazTsql</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Running *.XDF files using RevoScaleR computational functions versus have dataset available in Columnstore table or in In-Memory OLTP table will be focus of comparison for this blog post.</p>
<p>For this test, I will use the AirLines dataset, available <a target="_blank" rel="nofollow" href="https://packages.revolutionanalytics.com/datasets/">here</a>. Deliberately, I have picked a sample 200 MB (of 13GB dataset) in order to properly test the differences and what should be the best way.</p>
<p>After unzipping the file, I will use following T-SQL query to import the file into SQL Server.</p>
<p>With this example, you can import xdf file directly to SQL Server table (note, that I have transformed a CSV file into XDF and import xdf file into SQL table):</p>
<pre>-- must have a write permissions on folder: C:/Program Files/Microsoft SQL Server/130/R_SERVER/library/RevoScaleR/SampleData
DECLARE @RScript nvarchar(max)
SET @RScript = N'library(RevoScaleR)
                rxOptions(sampleDataDir = &quot;C:/Program Files/Microsoft SQL Server/130/R_SERVER/library/RevoScaleR/SampleData&quot;)
                inFile &lt;- file.path(rxGetOption(&quot;sampleDataDir&quot;), &quot;airsample.csv&quot;)
                of &lt;-  rxDataStep(inData = inFile, outFile = &quot;C:/Program Files/Microsoft SQL Server/130/R_SERVER/library/RevoScaleR/SampleData/airline20170428_2.xdf&quot;, 
                             transformVars = c(&quot;ArrDelay&quot;, &quot;CRSDepTime&quot;,&quot;DayOfWeek&quot;)
                            ,transforms = list(ArrDelay = as.integer(ArrDelay), CRSDepTime = as.numeric(CRSDepTime), DayOfWeek = as.character(DayOfWeek))
                            ,overwrite = TRUE
                            ,maxRowsByCols = 10000000
                            ,rowsPerRead = 200000)
                OutputDataSet &lt;- rxXdfToDataFrame(of)'

DECLARE @SQLScript nvarchar(max)
SET @SQLScript = N'SELECT 1 AS N'

EXECUTE sp_execute_external_script
     @language = N'R'
    ,@script = @RScript
    ,@input_data_1 = @SQLScript
WITH RESULT SETS ((ArrDelay INT
                    ,CRSDepTime DECIMAL(6,4)
                    ,DofWeek NVARCHAR(20)))
GO</pre>
<p> </p>
<p>So the whole process is to be done by creating a table, converting the above sp_execute_external_script into procedure and import results from external procedure to the table.</p>
<pre>--Complete process
CREATE TABLE AirFlights_small 
(id INT IDENTITY(1,1)
,ArrDelay INT
,CRSDepTime DECIMAL(6,4)
,DofWeek NVARCHAR(20) 
);
GO

CREATE Procedure ImportXDFtoSQLTable
AS
DECLARE @RScript nvarchar(max)
SET @RScript = N'library(RevoScaleR)
                rxOptions(sampleDataDir = &quot;C:/Program Files/Microsoft SQL Server/130/R_SERVER/library/RevoScaleR/SampleData&quot;)
                inFile &lt;- file.path(rxGetOption(&quot;sampleDataDir&quot;), &quot;airsample.csv&quot;)
                of &lt;-  rxDataStep(inData = inFile, outFile = &quot;airline20170428_2.xdf&quot;, 
                transformVars = c(&quot;ArrDelay&quot;, &quot;CRSDepTime&quot;,&quot;DayOfWeek&quot;)
            ,transforms = list(ArrDelay = as.integer(ArrDelay), CRSDepTime = as.numeric(CRSDepTime), DayOfWeek = as.character(DayOfWeek))
            ,overwrite = TRUE
            ,maxRowsByCols = 10000000)
             OutputDataSet &lt;- data.frame(rxReadXdf(file=of, varsToKeep=c(&quot;ArrDelay&quot;, &quot;CRSDepTime&quot;,&quot;DayOfWeek&quot;)))'
DECLARE @SQLScript nvarchar(max)
SET @SQLScript = N'SELECT 1 AS N'
EXECUTE sp_execute_external_script
     @language = N'R'
    ,@script = @RScript
    ,@input_data_1 = @SQLScript
WITH RESULT SETS ((ArrDelay INT,CRSDepTime DECIMAL(6,4),DofWeek NVARCHAR(20)));
GO

INSERT INTO AirFlights_small
EXECUTE ImportXDFtoSQLTable;
GO</pre>
<p> </p>
<p>There you go. Data are in T-SQL Table. Now we can start with comparisons.  I will be measuring the time to get average air delay time per day of the week.</p>
<p><img sizes="(max-width: 269px) 100vw, 269px" data-image-description="" data-orig-file="https://tomaztsql.files.wordpress.com/2017/04/2017-04-28-22_44_10-rstudio.png?w=456" data-orig-size="269,170" data-image-title="2017-04-28 22_44_10-RStudio" class="wp-image-4416" data-comments-opened="1" data-recalc-dims="1" data-attachment-id="4416" data-permalink="https://tomaztsql.wordpress.com/2017/04/28/performance-differences-between-revoscaler-columnstore-table-and-in-memory-oltp-table/2017-04-28-22_44_10-rstudio/#main" alt="2017-04-28 22_44_10-RStudio" data-medium-file="https://tomaztsql.files.wordpress.com/2017/04/2017-04-28-22_44_10-rstudio.png?w=456?w=269" data-large-file="https://tomaztsql.files.wordpress.com/2017/04/2017-04-28-22_44_10-rstudio.png?w=456?w=269" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://tomaztsql.files.wordpress.com/2017/04/2017-04-28-22_44_10-rstudio.png?w=456"></p>
<h3>RevoScaleR</h3>
<p>With using the RevoScaleR package, I will be using rxCrossTabs function with the help of transform argument to convert day of the week into factors:</p>
<pre>#importing data
outFile2 &lt;- rxDataStep(inData = inFile, outFile = &quot;C:/Program Files/Microsoft SQL Server/130/R_SERVER/library/RevoScaleR/SampleData/airline20170428_2.xdf&quot;, 
            transformVars = c(&quot;ArrDelay&quot;, &quot;CRSDepTime&quot;,&quot;DayOfWeek&quot;)
           ,transforms = list(ArrDelay = as.integer(ArrDelay), CRSDepTime = as.numeric(CRSDepTime), DayOfWeek = as.character(DayOfWeek))
           ,overwrite = TRUE
           ,maxRowsByCols = 10000000)

of2 &lt;- data.frame(rxReadXdf(file=outFile2, varsToKeep=c(&quot;ArrDelay&quot;, &quot;CRSDepTime&quot;,&quot;DayOfWeek&quot;)))

summary(rxCrossTabs(ArrDelay~DayOfWeek
                    ,data = of2  #outFile2
                    ,transforms = transforms
                    ,blocksPerRead=300000), output=&quot;means&quot;)</pre>
<p>Now get those times:</p>
<pre># Getting times
system.time({ 
  summary(rxCrossTabs(ArrDelay~DayOfWeek
                      ,data = of2
                      ,transforms = transforms
                      ,blocksPerRead=300000), output=&quot;means&quot;)
  })</pre>
<p>With results of 7.8 on elapsed time and computation time of 3.8 second.</p>
<pre>Rows Read: 8400013, Total Rows Processed: 8400013, Total Chunk Time: 3.825 seconds 
Computation time: 3.839 seconds.
   user  system elapsed 
   2.89    0.37   <strong> 7.89 </strong></pre>
<p> </p>
<h3>T-SQL query without any specifics</h3>
<p>To have a baseline, let’s run the following query:</p>
<pre>SET STATISTICS TIME ON;
SELECT 
[DofWeek]
,AVG(ArrDelay) AS [means]
FROM
    AirFlights_small
GROUP BY 
    [DofWeek]
SET STATISTICS TIME OFF;</pre>
<p>And check these time statistics</p>
<h5> SQL Server Execution Times:<br>
CPU time = 6124 ms,  elapsed time = 2019 ms.<br>
Warning: Null value is eliminated by an aggregate or other SET operation.</h5>
<p>Obiously the CPU / computation time is higher, although the elapsed time is faster.</p>
<h3>ColumnStore Table</h3>
<p>Let’s create a nonclustered column store index.</p>
<pre>CREATE TABLE AirFlights_CS
(id INT IDENTITY(1,1)
,ArrDelay INT
,CRSDepTime DECIMAL(6,4)
,DofWeek NVARCHAR(20) 
);
GO
INSERT INTO AirFlights_CS(ArrDelay, CRSDepTime, DofWeek)
SELECT ArrDelay, CRSDepTime, DofWeek FROM AirFlights_small 

CREATE NONCLUSTERED COLUMNSTORE INDEX NCCI_AirFlight
ON AirFlights_CS
(id, ArrDelay, CRSDepTime, DofWeek);
GO</pre>
<p>With the execution of the same query</p>
<pre>SET STATISTICS TIME ON;
SELECT 
[DofWeek]
,AVG(ArrDelay) AS [means]
FROM
  AirFlights_CS
GROUP BY     [DofWeek] SET STATISTICS TIME OFF;</pre>
<p>The following time statistics are in</p>
<h5> SQL Server Execution Times:<br>
CPU time = 202 ms,  elapsed time = 109 ms.<br>
Warning: Null value is eliminated by an aggregate or other SET operation.</h5>
<p> </p>
<h3>In-Memory OLTP</h3>
<p>To get Memory optimized table, we need to add a filegroup and create a table with memory optimized turned on:</p>
<pre>CREATE TABLE dbo.AirFlight_M   
(  
  id INT NOT NULL PRIMARY KEY NONCLUSTERED
 ,ArrDelay INT
 ,CRSDepTime DECIMAL(6,4) 
 ,DofWeek NVARCHAR(20)
) WITH (MEMORY_OPTIMIZED=ON, DURABILITY = SCHEMA_AND_DATA);
GO</pre>
<p>And insert the data</p>
<pre>INSERT INTO AirFlight_M
SELECT * FROM AirFlights_small</pre>
<p>Running the simple query</p>
<pre>SET STATISTICS TIME ON;
SELECT 
[DofWeek]
,AVG(ArrDelay) AS [means]
FROM
    AirFlight_M
GROUP BY 
    [DofWeek]
SET STATISTICS TIME OFF;</pre>
<p>results are:</p>
<h5> SQL Server Execution Times:<br>
CPU time = 6186 ms,  elapsed time = 1627 ms.<br>
Warning: Null value is eliminated by an aggregate or other SET operation.</h5>
<p>These results were somehow expected, mostly because the ColumnStore table is the only one having index and reading (also by looking in execution plans) optimized with comparison to others. Also degree of parallelism, clustered and non-clustered index can  be pushed, but the idea was to have tests similar to the one in RevoScaleR and R environemnt. With R, we can not push any index on the XDF file.</p>
<p>In R we run:</p>
<pre>system.time({ 
LMResults &lt;- rxLinMod(ArrDelay ~ DayOfWeek, data = outFile2, transforms = transforms)
LMResults$coefficients
})

</pre>
<p>And in SSMS we run:</p>
<pre>SET STATISTICS TIME ON;
-- 1. T-SQL
DECLARE @RScript nvarchar(max)
SET @RScript = N'library(RevoScaleR)
                LMResults &lt;- rxLinMod(ArrDelay ~ DofWeek, data = InputDataSet)
                OutputDataSet &lt;- data.frame(LMResults$coefficients)'
DECLARE @SQLScript nvarchar(max)
SET @SQLScript = N'SELECT ArrDelay, DofWeek FROM [dbo].[AirFlights_small]'
EXECUTE sp_execute_external_script
     @language = N'R'
    ,@script = @RScript
    ,@input_data_1 = @SQLScript
WITH RESULT SETS ((
            --DofWeek NVARCHAR(20)
        --    ,
            Coefficient DECIMAL(10,5)
            ));
GO
SET STATISTICS TIME OFF;


SET STATISTICS TIME ON;
-- 2. ColumnStore
DECLARE @RScript nvarchar(max)
SET @RScript = N'library(RevoScaleR)
                LMResults &lt;- rxLinMod(ArrDelay ~ DofWeek, data = InputDataSet)
                OutputDataSet &lt;- data.frame(LMResults$coefficients)'
DECLARE @SQLScript nvarchar(max)
SET @SQLScript = N'SELECT ArrDelay, DofWeek FROM [dbo].[AirFlights_CS]'
EXECUTE sp_execute_external_script
     @language = N'R'
    ,@script = @RScript
    ,@input_data_1 = @SQLScript
WITH RESULT SETS ((
            --DofWeek NVARCHAR(20)
        --    ,
            Coefficient DECIMAL(10,5)
            ));
GO
SET STATISTICS TIME OFF;


SET STATISTICS TIME ON;
-- 3. Memory optimized
DECLARE @RScript nvarchar(max)
SET @RScript = N'library(RevoScaleR)
                LMResults &lt;- rxLinMod(ArrDelay ~ DofWeek, data = InputDataSet)
                OutputDataSet &lt;- data.frame(LMResults$coefficients)'
DECLARE @SQLScript nvarchar(max)
SET @SQLScript = N'SELECT ArrDelay, DofWeek FROM [dbo].[AirFlight_M]'
EXECUTE sp_execute_external_script
     @language = N'R'
    ,@script = @RScript
    ,@input_data_1 = @SQLScript
WITH RESULT SETS ((
            --DofWeek NVARCHAR(20)
        --    ,
            Coefficient DECIMAL(10,5)
            ));
GO
SET STATISTICS TIME OFF;</pre>
<p> </p>
<h3>Conclusion</h3>
<p>Gathering statistics on CPU time and elapsed time when running simple Linear regression, this is comparison:</p>
<pre>df_LR_comparison &lt;- data.frame (
  method = c(&quot;T-SQL&quot;, &quot;ColumnStore&quot;, &quot;Memory Optimized&quot;, &quot;RevoScaleR&quot;)
  ,CPUtime = c(3000,1625,2156,7689)
  ,ElapsedTime = c(14323,10851,10600,7760)
  )
library(ggplot2)

ggplot(df_LR_comparison, aes(method, fill=method)) + 
  geom_bar(aes(y=ElapsedTime), stat=&quot;identity&quot;) +
  geom_line(aes(y=CPUtime, group=1), color=&quot;white&quot;, size=3) +
  scale_colour_manual(&quot; &quot;, values=c(&quot;d1&quot; = &quot;blue&quot;, &quot;d2&quot; = &quot;red&quot;))+
  #scale_fill_manual(&quot;&quot;,values=&quot;red&quot;)+
  theme(legend.position=&quot;none&quot;)

</pre>
<p>Showing that elapsed time for R environment with RevoScaleR is fastest (and getting data from XDF), where as simple T-SQL run with sp_execute_external_script and using RevoScaleR gives the slowest response.</p>
<p><img sizes="(max-width: 700px) 100vw, 700px" data-image-description="" data-orig-file="https://tomaztsql.files.wordpress.com/2017/04/2017-04-29-00_43_10-plot-zoom.png?w=456" data-orig-size="956,782" data-image-title="2017-04-29 00_43_10-Plot Zoom" data-comments-opened="1" class="wp-image-4474" data-recalc-dims="1" data-attachment-id="4474" data-permalink="https://tomaztsql.wordpress.com/2017/04/28/performance-differences-between-revoscaler-columnstore-table-and-in-memory-oltp-table/2017-04-29-00_43_10-plot-zoom/#main" alt="2017-04-29 00_43_10-Plot Zoom" data-medium-file="https://tomaztsql.files.wordpress.com/2017/04/2017-04-29-00_43_10-plot-zoom.png?w=456?w=300" data-large-file="https://tomaztsql.files.wordpress.com/2017/04/2017-04-29-00_43_10-plot-zoom.png?w=456?w=700" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://tomaztsql.files.wordpress.com/2017/04/2017-04-29-00_43_10-plot-zoom.png?w=456"></p>
<p>In terms of CPU time (white line), Columnstore with RevoScaleR call through external procedure outperforms all others.</p>
<p>Final conclusion: When running statistical analysis (using RevoScaleR or any other R library), use columnstore and index optimized tables/views to receive best CPU and elapsed times.  Important to remember is also the fact, that any aggregations and calculations that can be done within SQL Server, are better to be perfomered there.</p>
<p> </p>
<p>As always, code is available at <a target="_blank" rel="nofollow" href="https://github.com/tomaztk/Performance-differences-between-RevoScaleR-ColumnStore-Table-and-In-Memory-OLTP-Table">GitHub</a>.</p>
<p> </p>
<p>Happy coding! <img alt="🙂" class="wp-smiley" src="https://i0.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p> <a target="_blank" rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tomaztsql.wordpress.com/4375/"><img alt="" src="http://feeds.wordpress.com/1.0/comments/tomaztsql.wordpress.com/4375/" border="0"></a> <img alt="" src="https://i1.wp.com/pixel.wp.com/b.gif?resize=1%2C1&ssl=1" border="0" data-recalc-dims="1"></p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://tomaztsql.wordpress.com/2017/04/28/performance-differences-between-revoscaler-columnstore-table-and-in-memory-oltp-table/"> R – TomazTsql</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/E5__mSjDLDA"></a></div>