2011-12-15 3 views
1

J'ai une énorme base de données d'entreprises (environ 500 000) avec code postal, adresse, etc. J'ai besoin de les afficher par ordre croissant de 100 miles sont des utilisateurs de code postal. J'ai une table pour les codes postaux avec latitude et longitude. Quelle sera la solution la plus rapide/meilleure?Calcul de distance avec énorme base de données SQL Server

Cas 1: pour calculer la distance et trier par distance. Je vais avoir les utilisateurs code postal actuel, la latitude et la longitude en session. Je vais calculer la distance en utilisant une fonction SQL Server. Cas n ° 2: pour obtenir tous les codes postaux dans la zone de 50 miles et obtenir des entreprises avec tous ces codes postaux. Ici, je vais devoir écrire une sélection dans une requête imbriquée tout en trouvant des entreprises.

Je pense que le cas 1 va calculer la distance pour toutes les entreprises dans la base de données. Alors que le deuxième cas ira chercher les codes postaux et finira par aller chercher seulement les entreprises requises. Par conséquent, le cas 2 devrait être meilleur? J'apprécierais toute suggestion ici.

est ici question LINQ je pour le cas 1.

var businessListQuery = (from b in _DB.Businesses 
         let distance = _DB.CalculateDistance(b.Zipcode,userLattitude,userLogntitude) 
         where b.BusinessCategories.Any(bc => bc.SubCategoryId == subCategoryId) 
             && distance < 100 
         orderby distance 
         select new BusinessDetails(b, distance.ToString())); 

int totalRecords = businessListQuery.Count(); 
var ret = businessListQuery.ToList().Skip(startRow).Take(pageSize).ToList(); 

sur une application de la note de côté est en C#.

Merci

+2

Écrivez le sql et exécutez les plans et les statistiques d'exécution et voyez ce qui est plus rapide. Si la performance est un problème, écrivez une procédure stockée et faites-le dans la base de données et comparez-la également. –

+0

Créez l'index et utilisez Zipcode dans votre indexation, il vous donnera un résultat plus rapide de cette façon ou peut changer votre base d'index sur votre recherche et votre commande. – KuldipMCA

+0

méthode simple et très rapide http://stackoverflow.com/questions/3983325/calculate-distance-entre-zip-codes-and-users/3989830#3989830 –

Répondre

4

Vous pourriez faire pire que regarder le GEOGRAPHY type de données, par exemple:

CREATE TABLE Places 
(
    SeqID  INT IDENTITY(1,1), 
    Place  NVARCHAR(20), 
    Location GEOGRAPHY 
) 
GO 
INSERT INTO Places (Place, Location) VALUES ('Coventry', geography::Point(52.4167, -1.55, 4326)) 
INSERT INTO Places (Place, Location) VALUES ('Sheffield', geography::Point(53.3667, -1.5, 4326)) 
INSERT INTO Places (Place, Location) VALUES ('Penzance', geography::Point(50.1214, -5.5347, 4326)) 
INSERT INTO Places (Place, Location) VALUES ('Brentwood', geography::Point(52.6208, 0.3033, 4326)) 
INSERT INTO Places (Place, Location) VALUES ('Inverness', geography::Point(57.4760, -4.2254, 4326)) 
GO 
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location)/1000 AS DistanceInKilometres 
    FROM Places p1 
    CROSS JOIN Places p2 
GO 
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location)/1000 AS DistanceInKilometres 
    FROM Places p1 
     INNER JOIN Places p2 ON p1.SeqID > p2.SeqID 
GO 

geography::Point prend la latitude et la longitude ainsi qu'un SRID (numéro spécial ID de référence). Dans ce cas, le SRID est 4326, qui est la latitude et la longitude standard. Comme vous avez déjà la latitude et la longitude, vous pouvez simplement ajouter la colonne ALTER TABLE puis UPDATE pour le peupler.

J'ai montré deux façons d'extraire les données de la table, mais vous ne pouvez pas créer une vue indexée avec ceci (les vues indexées ne peuvent pas avoir de jointures individuelles). Vous pourriez cependant créer une table secondaire qui est effectivement un cache, qui est rempli en fonction de ce qui précède. Vous devez ensuite vous soucier de le maintenir (cela pourrait se faire à l'aide de déclencheurs ou d'un autre processus). Notez que la jointure croisée vous donnera 250 000 000 000 lignes, mais la recherche est simple car il vous suffit de regarder l'une des colonnes des lieux (par exemple, SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100, la seconde vous donnera beaucoup moins de lignes, mais la requête doit alors considérez les colonnes Place1 et Place2).

Questions connexes