ThinkGeo.com    |     Documentation    |     Premium Support

SQL2008 Performance versus Shapefiles

Hi,


Do you have any performance comparisons that demonstrate if SQL2008 layers perform better or worse than shapefiles on the file system with spatial indexes?


I am interested in first map loading times (where one would assume the SQL2008 layer would be slower due to overhead) as well as how the amount of data (more points, lines) affects the maps performance with a SQL2008 layer versus a shapefile layer.


For example on a larger or smaller dataset is the SQL overhead worth the convenience of storing the data in a SQL database?


Finally do you have a sample SQL2008 database that I could restore from so that I get an idea of the correct structure thats works with Map Suite?



Hi Steve,


The current MsSql2008FeatureLayer (3.1.16) doesn't have a good performance. 

We have done a lot of enhancements on that which will be integrated in the upcoming version. 


With the future patch, we get a much better performance for Sql 2008 feature layer. But its performance

still cannot be as good as what shapefile is. Generally, it's 1 time slower than shape file. 

Here are some performance test results.



    
        
            
            Record count in specify extent
            
            
            MsSql2008FeatureLayer(s)
            
            
            ShapeFileFeatureLayer(s)
            
        
        
            
            64,924
            
            
            8.11
            
            
            3.45
            
        
        
            
            20,078
            
            
            2.62
            
            
            1.27
            
        
        
            
            2,533
            
            
            0.42
            
            
            0.24
            
        
    


You can see the MsSql2008FeatureLayer's performance is around 50% of ShapeFileFeatureLayer. 
 
ShapeFile also has index file which can render map faster.
We did another test about the Open() method in both way, and we found loading from 

SQL Server is slow at the first time only and become fast from the second time. 

But it’s still slower than loading from ShapeFile.
 
We don't have a restorable SQL2008 database but by following the steps here (gis.thinkgeo.com/Support/Dis...fault.aspx),  

you can easily create one by yourself with a 3rd part tool, which you can get here 

(sharpgis.net/page/SQL-Se...Tools.aspx)) 
Finally, just reminds you there are a couple steps need to do for a higher performance. 

a. Specify the right Srid property by using MsSql2008FeatureLayer.Srid. 

b. Build the Index properly.
For detail, please see the post here (gis.thinkgeo.com/Support/Dis...fault.aspx)
 
If you have any questions please let me know.
 
Thanks,
 
Howard

Hi Howard, 
  
 Would you please expand your performance testing with 20 concurrent users, 50 users, 100 users, 200 users environments? 
  
 Thanks.




 




Kevin,


Here is the test. Generally, we simulate different number of concurrent users accessing the same database at the same time. Every user calls the method GetFeaturesInsideBoundingBox() 100 times with a random input extent. In our test,  we uses a remote Sql2008 Server and a remote shape file (on the same machine of the Sql2008 Server) which has the same data. We get the average time for one Operation (layer.Open / layer.GetFeaturesInsideBoundingBox / layer.Close) and here is the result.


 



       
    
        
            
            

User Count


            
            
            

Remote Sql2008 (ms)


            
            
            

Remote ShapeFile(ms)


            
        
        
            
            

1


            
            
            

9.77


            
            
            

11.9


            
        
        
            
            

10


            
            
            

52.12


            
            
            

84.8


            
        
        
            
            

20


            
            
            

103


            
            
            

177.6


            
        
        
            
            

50


            
            
            

273


            
            
            

459


            
        
        
            
            

100


            
            
            

583


            
            
            

1431


            
        
    

So we can see,  remote Sql2008 server is (1.5 to 2.5) times faster than a remote Shapefile under the same circumstance.


We also compared the average time between a Local ShapeFile and a Local Sql2008 Server. The result is interesting that the average time for an operation with a local shapeFile is almost the same no matter how many concurrent users are there, but for the local sql2008 server, it still grows linearly. I think that's because the operating system did pretty good caching for a local file, but didn't do much caching for a database. In the test we also found if we change the file path to a network path like “\\192.168.0.10\Share\Test.shp” instead of a local one like “c:\Share\Test.shp”, although the file is still the same , the performance will be much slower, in fact it will be about 1.5 to 2 times slower than the local Sql2008 server.


 



       
    
        
            
            

User Count


            
            
            

Local ShapeFile(ms)


            
            
            

Local Sql2008 (ms)


            
        
        
            
            

1


            
            
            

4.8


            
            
            

6.28


            
        
        
            
            

10


            
            
            

6.68


            
            
            

61.13


            
        
        
            
            

20


            
            
            

4.84


            
            
            

127


            
        
        
            
            

50


            
            
            

7.89


            
            
            

360


            
        
        
            
            

100


            
            
            

7.09


            
            
            

762


            
        
    

So we can say, the local shape file has the best performance because it is well cached. Other than that, Sql Server2008 will be around 2 times faster than a Shape File under the same circumstance.


Here is the key codes in the test. You can try if you are interested.



 List<long> results = new List<long>();

        // Start Sql Test 
        private void btnSql2008Test_Click(object sender, EventArgs e)
        {
            results.Clear();
            int times = Convert.ToInt32(txtSql2008TestTimes.Text.Trim());
            TestMultiThread(new ThreadStart(TestOneThreadOnSql2008), times);
        }

        // Start Shape File Test 
        private void btnShapeFileTest_Click(object sender, EventArgs e)
        {
            results.Clear();
            int times = Convert.ToInt32(txtShapeTestTimes.Text.Trim());
            TestMultiThread(new ThreadStart(TestOneThreadOnShapeFileFeatureLayer), times);
            }
        // Show Result
        private void btnShowResult_Click(object sender, EventArgs e)
        {
            long sum = 0;
            foreach (long item in results)
            {
                sum += item;
            }
            MessageBox.Show(((double)sum/(double)results.Count).ToString());
        }


        private void TestMultiThread(ThreadStart threadStart, int clients)
        {
            Thread[] threads = new Thread[clients];
            for (int i = 0; i < threads.Length; i++)
            {
                threads[i] = new Thread(threadStart);
                threads[i].Start();
            }
        }

        private void TestOneThreadOnSql2008()
        {
            string connectString = @"Data Source=192.168.0.191\TGSQLSERVER; Initial Catalog=InternalDB; User ID=userId; Password=password;";
            TempMsSql2008FeatureLayer sql2008Layer = new TempMsSql2008FeatureLayer(connectString, "states", "recid");
            Take100Operations(sql2008Layer);
        }


        private void TestOneThreadOnShapeFileFeatureLayer()
        {
            ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(@"C:\Share\USStates.shp");
            Take100Operations(shapeFileFeatureLayer);
        }

        private void Take100Operations(FeatureLayer sql2008Layer)
        {
            Random random = new Random(DateTime.Now.Millisecond);
            // Do 100 operations
            for (int i = 0; i < 10; i++)
            {
                RectangleShape extent = new RectangleShape(-126.4, 48.8, -67.0, 19.0);
                extent.ScaleDown(50);
                for (int j = 0; j < 10; j++)
                {
                    extent.TranslateByOffset(random.Next(10), random.Next(10), GeographyUnit.Meter, DistanceUnit.Meter);
                    GetFeaturesWithinRectangle(sql2008Layer, extent);
                }
            }
        }

        private Collection<Feature> GetFeaturesWithinRectangle(FeatureLayer layer, RectangleShape extent)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            layer.Open();
            Collection<Feature> features = layer.QueryTools.GetFeaturesInsideBoundingBox(extent, ReturningColumnsType.AllColumns);
            layer.Close();
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            results.Add(sw.ElapsedMilliseconds);
            return features;
        }

Thanks,


Ben


 


 



Kevin, 
  
 Just let you know we were using Desktop for the test. For Web it is the same as their core part are the same. Just changing lines of code you can make it working. 
  
 Ben

Thanks, Ben. 



When you have time, would you please run your code to get Features from a "Census Tract" layer?   A "Census Tract" layer has much more features than US states layer.  



In my case, it is very hard for me to deploy the shape files to my users machines.  Users will access these shape files from a file server, or retrieve data from a sql server or call a service which runs on sql server or a application server to get data.


Question:


Is there any easier and faster way to bind my custom data into a sql2008 layer other than using CustomColumnFetch?  



Kevin, 
  
 You mean the “Census Track” data in TIGER? As every county has a Census Track data and the size differs a lot,  what’s the size you want to test, and what operations you want to test most?   
  
 If you want to test on a specific type of data and get an absolute performance result, I suggest you to test in your own environment with your own data. As our test environment is different from yours, it’s fine to provide a general result like which method is faster, but the specific number does not make much sense. You can easily make the above code working by lines of changes on your computer, and feel free to let us know if you need any help. 
  
 As you cannot deploy the shape file to users’ machines, maybe you need to choose Sql2008 Server which is faster than a remote file in our test. 
  
 You can create your own Sql2008 layer by inheriting from the general one, override the DrawCore method and bind your custom data there.  For different scenarios, there are different ways to integrate. I think that’s all straightforward though. :) Let us know your concrete scenario maybe we can provide an easier way. 
  
 Thanks, 
  
 Ben