Suite

Un moyen d'accélérer l'ajout de données à la base de données SDE alors qu'elle est toujours versionnée ?


Mon groupe travaille sur une base de données et environ une fois par mois je reçois des données qu'il faut annexer. Ce processus m'a obligé à réconcilier et à publier toutes les versions par défaut. Je retire ensuite la base de données localement et supprime toutes les classes de relations et le réseau géométrique afin de pouvoir les ajouter aux nouvelles données. Ensuite, je recharge la base de données, enregistre les données, recrée des versions et accorde des privilèges. Y a-t-il un moyen de contourner ce processus?


Rsync peut-il reprendre après avoir été interrompu ?

J'ai utilisé rsync pour copier un grand nombre de fichiers, mais mon système d'exploitation (Ubuntu) a redémarré de manière inattendue.

Après le redémarrage, j'ai réexécuté rsync, mais à partir de la sortie sur le terminal, j'ai constaté que rsync copiait toujours ceux déjà copiés auparavant. Mais j'ai entendu dire que rsync est capable de trouver des différences entre la source et la destination, et donc de simplement copier les différences. Alors je me demande dans mon cas si rsync peut reprendre ce qui restait la dernière fois ?


1 réponse 1

Votre meilleur pari sera d'utiliser SSIS ou alors INSERTION EN VRAC. Il existe diverses améliorations de performances que vous pouvez apporter lorsque vous les utilisez et elles sont très bien documentées dans le Guide des performances de chargement de données.

À SSIS niveau, vous pouvez examiner les éléments ci-dessous pour accélérer la lecture et le chargement des données :

    Option avec ses limites.
  • Utilisez le fournisseur OLE DB SQL Server Native Client 10.x pour une connexion en mémoire hautes performances
  • Définissez la taille du paquet sur 32767
  • Sélectionnez l'option "Table ou vue - chargement rapide" du mode d'accès aux données de destination OLE DB

Vous trouverez ci-dessous quelques bons moyens d'améliorer les opérations BULK INSERT :

  1. Utilisation de TABLOCK comme indicateur de requête.
  2. Suppression des index pendant l'opération de chargement en bloc, puis une fois celle-ci terminée, les recréer.
  3. Modification du modèle de récupération de la base de données en BULK_LOGGED pendant l'opération de chargement.
  4. Si la cible a un index clusterisé, la spécification de la clause ORDER BY dans l'opération d'insertion en bloc augmentera la vitesse de chargement en bloc.
  5. Utilisation de l'indicateur de trace 610 au début de l'opération BULK INSERT.

Le degré maximum de parallélisme doit être configuré sur le serveur plutôt que par défaut. Vous pouvez vous référer à ma réponse sur la façon dont il le configure ici.

Si vous utilisez SQL Server 2014, SELECT . INTO est parallèle.

Aussi, vous devez surveiller Statistiques d'attente sur le serveur, en particulier SOS_SCHEDULER_YIELD, ce qui entraîne un conflit de planificateur sur les serveurs dotés de plusieurs processeurs exécutant des opérations de chargement en bloc simultanées et en concurrence pour les mêmes cycles de processeur.


15 réponses 15

Un peu trop tard avec cette réponse, mais comme j'étais confronté à une question similaire, j'ai fait un test avec JMeter et un serveur MySQL sur la même machine, où j'ai utilisé :

  1. Un contrôleur de transaction (générateur de l'échantillon parent) qui contenait deux requêtes JDBC : une instruction Delete et une instruction Insert
  2. Une demande JDBC distincte contenant l'instruction Update.

Après avoir effectué le test pour 500 boucles, j'ai obtenu les résultats suivants :

DEL + INSERT - Moyenne : 62 ms

Plus le tableau est grand (nombre et taille de colonnes), plus il devient coûteux de le supprimer et de l'insérer plutôt que de le mettre à jour. Parce que vous devez payer le prix de UNDO et REDO. Les DELETE consomment plus d'espace UNDO que les UPDATE, et votre REDO contient deux fois plus d'instructions que nécessaire.

En outre, c'est tout à fait faux d'un point de vue commercial. Considérez combien il serait plus difficile de comprendre une piste d'audit théorique sur cette table.

Il existe certains scénarios impliquant des mises à jour en bloc de toutes les lignes d'une table où il est plus rapide de créer une nouvelle table en utilisant CTAS à partir de l'ancienne table (en appliquant la mise à jour dans la projection de la clause SELECT), en supprimant l'ancienne table et en renommant le nouveau tableau. Les effets secondaires sont la création d'index, la gestion des contraintes et le renouvellement des privilèges, mais cela vaut la peine d'être considéré.

Une commande sur la même ligne doit toujours être plus rapide que deux sur cette même ligne. Donc, la MISE À JOUR seulement serait mieux.

ÉDITER dresser le tableau :

exécutez ceci, ce qui prend 1 seconde sur mon système (serveur sql 2005):

lancez ceci, ce qui a pris 2 secondes sur mon système :

Je crains que le corps de votre question ne soit lié à la question du titre.

En SQL, UPDATE est-il toujours plus rapide que DELETE+INSERT ?

De telles mises à jour entraînent une réalisation plus coûteuse (plus de traitement) de la mise à jour par insertion+mise à jour que par insertion+mise à jour directe. Ce sont les cas où

  • on met à jour le champ avec une clé unique (ou primaire) ou
  • lorsque les nouvelles données ne rentrent pas (sont plus grandes) dans l'espace de ligne alloué avant la mise à jour (ou même la taille de ligne maximale), entraînant une fragmentation,
  • etc.

Ma recherche rapide (non exhaustive), sans prétendre en couvrir une, m'a donné [1], [2]

[1]
Opérations de mise à jour
(Guide des performances et de l'optimisation de Sybase® SQL Server
Chapitre 7 : L'optimiseur de requêtes SQL Server)
http://www.lcard.ru/

Gardez à l'esprit que la fragmentation réelle qui se produit lorsque DELETE+INSERT est émis par opposition à une mise à jour correctement implémentée fera une grande différence dans le temps.

C'est pourquoi, par exemple, REPLACE INTO que MySQL implémente est déconseillé plutôt que d'utiliser INSERT INTO . SUR LA MISE À JOUR DE LA CLÉ EN DOUBLE . syntaxe.

Je viens d'essayer de mettre à jour 43 champs sur une table avec 44 champs, le champ restant était la clé principale en cluster.

La mise à jour a pris 8 secondes.

Une suppression + insertion est plus rapide que l'intervalle de temps minimum que les "Statistiques client" rapportent via SQL Management Studio.

Dans votre cas, je pense que la mise à jour sera plus rapide.

Vous avez défini une clé primaire, elle deviendra probablement automatiquement un index cluster (au moins SQL Server le fait). Un index de cluster signifie que les enregistrements sont physiquement déposés sur le disque en fonction de l'index. L'opération DELETE elle-même ne causera pas beaucoup de problèmes, même après la disparition d'un enregistrement, l'index reste correct. Mais lorsque vous INSÉREZ un nouvel enregistrement, le moteur de base de données devra placer cet enregistrement à l'emplacement correct, ce qui, dans certaines circonstances, entraînera un "remaniement" des anciens enregistrements pour "faire place" à un nouveau. Là où il va ralentir l'opération.

Un index (en particulier en cluster) fonctionne mieux si les valeurs augmentent sans cesse, de sorte que les nouveaux enregistrements sont simplement ajoutés à la queue. Vous pouvez peut-être ajouter une colonne INT IDENTITY supplémentaire pour devenir un index clusterisé, cela simplifiera les opérations d'insertion.

La question de la vitesse n'est pas pertinente sans problème de vitesse spécifique.

Si vous écrivez du code SQL pour modifier une ligne existante, vous la METTRE À JOUR. Tout le reste est incorrect.

Si vous allez enfreindre les règles de fonctionnement du code, alors vous feriez mieux d'avoir une sacrée bonne raison quantifiée, et pas une vague idée de "Ce chemin est plus rapide", quand vous n'en avez pas idée de ce qu'est "plus rapide".

Que faire si vous avez quelques millions de lignes. Chaque ligne commence par une donnée, peut-être un nom de client. Au fur et à mesure que vous collectez des données pour les clients, leurs entrées doivent être mises à jour. Supposons maintenant que la collecte des données client est répartie sur de nombreuses autres machines à partir desquelles elles sont ensuite collectées et mises dans la base de données. Si chaque client dispose d'informations uniques, vous ne seriez pas en mesure d'effectuer une mise à jour en masse, c'est-à-dire qu'il n'y a pas de critère de clause Where à utiliser pour mettre à jour plusieurs clients en une seule fois. D'autre part, vous pouvez effectuer des insertions en masse. Ainsi, la question pourrait être mieux posée comme suit : est-il préférable d'effectuer des millions de mises à jour uniques, ou est-il préférable de les compiler en suppressions et insertions en masse volumineuses. En d'autres termes, au lieu de "mettre à jour [table] set field=data where clientid=123" un million de fois, vous supprimez de [table] où clientid in ([tous les clients à mettre à jour]) insérez dans [table] valeurs (données pour client1), (données pour client2), etc'

L'un ou l'autre choix est-il meilleur que l'autre, ou êtes-vous foutu dans les deux sens ?

Supprimer + Insérer est presque toujours plus rapide car une mise à jour comporte beaucoup plus d'étapes.

  1. Recherchez la ligne en utilisant PK.
  2. Lire la ligne à partir du disque.
  3. Vérifiez quelles valeurs ont changé
  4. Déclenchez le déclencheur onUpdate avec les variables :NEW et :OLD renseignées

Écrire de nouvelles variables sur le disque (la ligne entière)

(Ceci se répète pour chaque ligne que vous mettez à jour)

Mettre à jour l'index PK avec les emplacements des nouveaux enregistrements.

(Cela ne se répète pas, tout peut être effectué en un seul bloc d'opération).

Utiliser Insérer + Supprimer fragmentera votre système de fichiers, mais pas si rapidement. Faire une optimisation paresseuse en arrière-plan libérera toujours les blocs inutilisés et emballera complètement la table.

Évidemment, la réponse varie en fonction de la base de données que vous utilisez, mais UPDATE peut toujours être implémenté plus rapidement que DELETE+INSERT. Étant donné que les opérations en mémoire sont pour la plupart triviales de toute façon, étant donné une base de données basée sur un disque dur, une MISE À JOUR peut modifier un champ de base de données en place sur le disque dur, tandis qu'une suppression supprimerait une ligne (en laissant un espace vide) et insèrerait un nouveau rangée, peut-être jusqu'à la fin du tableau (encore une fois, tout est dans l'implémentation).

L'autre problème mineur est que lorsque vous METTRE À JOUR une seule variable dans une seule ligne, les autres colonnes de cette ligne restent les mêmes. Si vous supprimez puis faites un INSERT, vous courez le risque d'oublier d'autres colonnes et par conséquent de les laisser de côté (auquel cas vous devrez faire un SELECT avant votre DELETE pour stocker temporairement vos autres colonnes avant de les réécrire avec INSERT) .

Cela dépend du produit. Un produit pourrait être implémenté qui (sous les couvertures) convertit toutes les mises à jour en un DELETE et un INSERT (emballés transactionnellement). À condition que les résultats soient cohérents avec la sémantique UPDATE.

Je ne dis pas que je connais un produit qui fait cela, mais c'est parfaitement légal.

Chaque écriture dans la base de données a de nombreux effets secondaires potentiels.

Supprimer : une ligne doit être supprimée, les index mis à jour, les clés étrangères vérifiées et éventuellement supprimées en cascade, etc. Insérer : une ligne doit être allouée - cela peut être à la place d'une ligne supprimée, peut-être pas les index doivent être mis à jour, les clés étrangères vérifié, etc. Mise à jour : une ou plusieurs valeurs doivent être mises à jour, peut-être que les données de la ligne ne rentrent plus dans ce bloc de la base de données, donc plus d'espace doit être alloué, ce qui peut se répercuter sur plusieurs blocs en cours de réécriture, ou conduire à des blocs fragmentés si la valeur a des contraintes de clé étrangère, elles doivent être vérifiées, etc.

Pour un très petit nombre de colonnes ou si la ligne entière est mise à jour Supprimer+insérer peut être plus rapide, mais le problème de contrainte FK est important. Bien sûr, vous n'avez peut-être plus de contraintes FK maintenant, mais cela sera-t-il toujours vrai ? Et si vous avez un déclencheur, il est plus facile d'écrire du code qui gère les mises à jour si l'opération de mise à jour est vraiment une mise à jour.

Un autre problème auquel il faut penser est que parfois l'insertion et la suppression détiennent des verrous différents de la mise à jour. La base de données peut verrouiller la table entière pendant que vous insérez ou supprimez, par opposition au verrouillage d'un seul enregistrement pendant que vous mettez à jour cet enregistrement.

En fin de compte, je suggérerais simplement de mettre à jour un enregistrement si vous souhaitez le mettre à jour. Vérifiez ensuite les statistiques de performances de votre base de données et les statistiques de cette table pour voir s'il y a des améliorations de performances à apporter. Tout le reste est prématuré.

Un exemple du système de commerce électronique sur lequel je travaille : nous stockions les données de transaction par carte de crédit dans la base de données selon une approche en deux étapes : d'abord, écrivez une transaction partielle pour indiquer que nous avons commencé le processus. Ensuite, lorsque les données d'autorisation sont renvoyées par la banque, mettez à jour l'enregistrement. Nous aurions pu supprimer puis réinsérer l'enregistrement, mais à la place, nous avons simplement utilisé la mise à jour. Notre DBA nous a dit que la table était fragmentée car la base de données n'allouait qu'une petite quantité d'espace pour chaque ligne, et la mise à jour a provoqué un chaînage de blocs car elle a ajouté beaucoup de données. Cependant, plutôt que de passer à SUPPRIMER + INSERER, nous venons de régler la base de données pour toujours allouer la ligne entière, cela signifie que la mise à jour pourrait utiliser l'espace vide préalloué sans problème. Aucun changement de code requis, et le code reste simple et facile à comprendre.


11 réponses 11

La meilleure solution semble être de versionner les noms de fichiers en ajoutant l'heure de la dernière modification.

Vous pouvez procéder de la manière suivante : ajoutez une règle de réécriture à votre configuration Apache, comme ceci :

Cela redirigera toute URL "versionnée" vers l'URL "normale". L'idée est de conserver les mêmes noms de fichiers, mais de bénéficier du cache. La solution pour ajouter un paramètre à l'URL ne sera pas optimale avec certains proxys qui ne mettent pas en cache les URL avec des paramètres.

Avec versionFile() ressemblant à ceci :

Et c'est tout! Le navigateur demandera image.123456789.png, Apache le redirigera vers image.png, vous bénéficierez donc du cache dans tous les cas et n'aurez aucun problème d'obsolescence, sans avoir à vous soucier de la gestion des versions des noms de fichiers .

Pourquoi ne pas simplement ajouter un numéro de "version" de chaîne de requête et mettre à jour la version à chaque fois ?

Il y a encore un peu de travail pendant la construction pour mettre à jour les numéros de version mais les noms de fichiers n'ont pas besoin de changer.

Renommer vos ressources est la voie à suivre, bien que nous utilisions un numéro de build et l'intégrions dans le nom du fichier au lieu d'un hachage MD5

car cela signifie que toutes vos ressources peuvent être renommées de manière déterministe et résolues au moment de l'exécution.

Nous utilisons ensuite des contrôles personnalisés pour générer des liens vers des ressources lors du chargement de la page en fonction du numéro de build qui est stocké dans un paramètre d'application.

Nous avons suivi un modèle similaire à PJP, en utilisant Rails et Nginx.

Nous voulions que les images d'avatar des utilisateurs soient mises en cache par le navigateur, mais lors d'un changement d'avatar, nous avions besoin que le cache soit invalidé dès que possible.

Nous avons ajouté une méthode au modèle d'avatar pour ajouter un horodatage au nom du fichier :

Partout dans le code où les avatars ont été utilisés, nous avons référencé cette méthode plutôt qu'une URL. Dans la configuration Nginx, nous avons ajouté cette réécriture :

Cela signifiait que si un fichier changeait, son URL dans le code HTML changeait, de sorte que le navigateur de l'utilisateur faisait une nouvelle demande pour le fichier. Lorsque la demande a atteint Nginx, elle a été réécrite sous le nom simple du fichier.

Je suggérerais d'utiliser la mise en cache par ETags dans cette situation, voir http://en.wikipedia.org/wiki/HTTP_ETag. Vous pouvez ensuite utiliser le hachage comme etag. Une demande sera toujours soumise pour chaque ressource, mais le navigateur ne téléchargera que les éléments qui ont changé depuis le dernier téléchargement.

Lisez la documentation de votre serveur Web / plate-forme sur la façon d'utiliser correctement les etags, la plupart des plates-formes décentes ont un support intégré.

La plupart des navigateurs modernes vérifient l'en-tête if-modified-since chaque fois qu'une ressource pouvant être mise en cache se trouve dans une requête HTTP. Cependant, tous les navigateurs ne prennent pas en charge l'en-tête if-modified-since.

Il existe trois façons de "forcer" le navigateur à charger une ressource mise en cache.

Option 1 Créez une chaîne de requête avec un numéro de version. src="https://stackoverflow.com/questions/3459252/script.js?ver=21" . L'inconvénient est que de nombreux serveurs proxy ne mettent pas en cache une ressource avec des chaînes de requête. Il nécessite également une mise à jour à l'échelle du site pour les modifications.

Option 2 Créez un système de nommage pour vos fichiers src="https://stackoverflow.com/questions/3459252/script083010.js" . Cependant, l'inconvénient de l'option 1 est que cela nécessite également des mises à jour à l'échelle du site chaque fois qu'un fichier change.

Option 3 Peut-être la solution la plus élégante, configurez simplement les en-têtes de mise en cache : dernière modification et expiration sur votre serveur. Le principal inconvénient de ceci est que les utilisateurs peuvent avoir à remettre en cache des ressources car elles ont expiré mais n'ont jamais changé. De plus, l'en-tête de dernière modification ne fonctionne pas correctement lorsque le contenu est servi à partir de plusieurs serveurs.


Vue spatiale si lente

J'ai une vue spatiale avec 25 colonnes dans le serveur de base de données qui ressemble à ceci :

SELECTIONNER a.OBJECTID, a.Shape, a.KEYID, a.ROTATION, a.LAND_COVER, a.LAND_USE, a.COMPANY, b.Species, b.SpeciesGroup, c.Tipe
DE sde.LANDUSE COMME JOINT EXTÉRIEUR GAUCHE
gdb.dbo.StandReg AS b ON a.KEYID = b.KEYID LEFT OUTER JOIN
(SELECT Dist, créé_par, mis à jour_par
DE gdb.dbo.Petak_PSDS
WHERE (Dist = 'District 1')) AS c ON a.KEYID = c.cKeyId

(la requête a été tronquée, toutes les colonnes ne sont pas mentionnées)

Cette vue se composait de 3 tableaux. La vue contient 7600 données. Je l'ouvre sur mon PC en utilisant arcmap / arccatalog et le chargement prend environ 4 minutes. J'ai utilisé analyser et update_dbms_stat et c'est toujours le même. De plus, il n'y a pas d'erreurs spatialement.
Comment puis-je le faire charger plus rapidement ?

BTW, la vue est-elle réplicable à l'aide de la réplication unidirectionnelle ?

[arcsde 10.0, serveur SQL 2005]

par VinceAngelo

Puisque vous utilisez SQL-Server 2005, la vue comporte cinq tables. je doute qu'il y ait
de toute façon, au-delà de s'assurer que tous les index sont présents, pour améliorer cette requête.
Cela pourrait être beaucoup plus rapide avec SQL-Server 2008 et un type de géométrie natif, mais
c'est probablement quelque chose à régler avec Microsoft (s'ils prennent encore en charge
2005 à cette date tardive).

BTW : si vous effectuez une mise à niveau vers une base de données moderne, assurez-vous de suivre au mieux
pratique, et chargez les tables de données en utilisant un propriétaire autre que SDE - le
L'utilisateur SDE doit être réservé à l'administration de l'instance.

par MarcoBoeringa

J'ai une vue spatiale avec 25 colonnes dans le serveur de base de données qui ressemble à ceci :
.
BTW, la vue est-elle réplicable à l'aide de la réplication unidirectionnelle ?
[arcsde 10.0, serveur SQL 2005]

Une vue est une vue, c'est-à-dire qu'elle ne contient pas de données en elle-même, elle ne fait référence qu'à des données existantes dans d'autres tables. Si vous répliquez les classes d'entités et les tables utilisées dans votre vue et copiez la définition de la vue dans la géodatabase enfant, vous devriez avoir la « vue » la plus à jour de la base de données après une synchronisation.

Il existe des options spécifiques pour / les choses à prendre en compte avec les classes de relations et la réplication, consultez l'aide pour cela :

Nous constatons que le stockage des données de forme au format SQL Server GEOMETRY a un ÉNORME impact négatif sur les performances. (Je viens de répondre à votre fil de discussion sur ce processus de migration.) Si vous faites cela, ce serait un endroit où chercher. Les vues existaient-elles avant votre conversion en GEOMETRIE ? Si oui, comment était la performance alors ?

Pour une classe d'entités surfaciques comportant environ 25 colonnes d'attributs, nous obtenons des taux de copie de données de seulement 7 à 9 entités par seconde, que nous utilisions Classe d'entités vers Classe d'entités, Copier les entités ou Ajouter. Les polygones sont basés sur des données à l'échelle 1:100 000 à la taille du comté (moyenne d'environ 2 100 sommets / entité) pour vous donner une idée du niveau de détail.

Il nous semble, au moins anecdotique, que pratiquement TOUTES les opérations de base de données sont plus lentes à 10,1 qu'elles ne l'étaient à 10,0 Nous nous asseyons et attendons juste qu'ArcCatalog se connecte à la géodatabase avant d'essayer de faire autre chose. Il semblait également, encore une fois uniquement au niveau des preuves anecdotiques, que les vues spatiales s'affichaient en réalité plus rapidement que la table spatiale sous-jacente (encore une fois, en utilisant des tables qui stockent les données d'entités dans SQL Server GEOMETRY par opposition au format SDE_BINARY).

Quelques autres fils de discussion que j'ai lus suggèrent qu'il existe un correctif pour SQL Server 2012, mais nous n'en sommes encore qu'à 2008R2. Ils disent également que la "solution" est de revenir à SDE_BINARY au lieu d'utiliser GEOMETRY, mais cela crée d'autres problèmes pour nous (nos vues spatiales ont inexplicablement cessé de fonctionner correctement, c'est pourquoi nous avons commencé par la route GEOMETRY en premier lieu) donc ce n'est pas une alternative viable.

Bien sûr, il y a le problème fondamental de savoir si les données clés de l'entreprise sur lesquelles vous effectuez les jointures SQL sont correctement indexées, ce qui peut avoir un impact énorme sur les performances, en particulier lorsque des milliers ou des dizaines de milliers de fonctionnalités sont impliquées.

par MarcoBoeringa

Pour une classe d'entités surfaciques comportant environ 25 colonnes d'attributs, nous obtenons des taux de copie de données de seulement 7 à 9 entités par seconde, que nous utilisions Classe d'entités vers Classe d'entités, Copier les entités ou Ajouter. Les polygones sont basés sur des données à l'échelle 1:100 000 à la taille du comté (moyenne d'environ 2 100 sommets / entité) pour vous donner une idée du niveau de détail.

Bien sûr, il y a le problème fondamental de savoir si les données clés de l'entreprise sur lesquelles vous effectuez les jointures SQL sont correctement indexées, ce qui peut avoir un impact énorme sur les performances, en particulier lorsque des milliers ou des dizaines de milliers de fonctionnalités sont impliquées.

Vous dites donc que vous avez plus de 10 000 entités comprenant en moyenne 2 100 sommets par entité à l'échelle 1 : 100 000 . :eek:

Ce flux de données est-il numérisé à partir d'images, sans jamais éliminer correctement les sommets inutiles ? Je ne peux pas imaginer un polygone / une ligne nécessitant jusqu'à 2100 sommets individuels pour définir sa forme à l'échelle 1:100.000. Même à l'échelle 1:1000, il serait hautement indésirable d'avoir une telle quantité de sommets par entité.

Pour une carte de base 1:1000 très détaillée et de haute qualité ici aux Pays-Bas du réseau routier national, où j'ai participé à la refonte du flux de travail basé sur la photogrammétrie et à la migration de la base de données il y a une dizaine d'années, un ensemble de données de test avait une moyenne d'environ 27 sommets par entité. , minimum 4, maximum 1026, mais c'était une rare exception.

L'écriture sur un ancien serveur Unix à processeur unique 100 MHz Sun Sparc Ultra-2, mais dédié et encore inutilisé, et le stockage dans SDE_BINARY, ont entraîné des vitesses de chargement des données d'environ 120 fonctionnalités/seconde, soit environ 27*120=3240 sommets/seconde. (Oracle

Encore une fois, nous parlons ici d'il y a >10 ans.

Vos données se chargent à 14700 à 18900 sommets par seconde. Je laisse aux autres le soin de commenter si c'est une vitesse normale en ce moment avec les détails de configuration que vous avez publiés. mais vous devrez peut-être vraiment reconsidérer votre flux de travail pour la collecte et le stockage de ces données.

par VinceAngelo

Les sommets par seconde sont une métrique très trompeuse. Je ne lui ferais pas trop confiance.

Les bases de données fonctionnent dans les transactions. Chaque LIGNE est traitée au total, ce qui comprend
LOBs et chaînes. Un point GeoNames à un sommet peut contenir de 8 à 10 000 données sur une seule ligne,
tandis qu'un polygone de sommets dense de 2k sans attributs pourrait facilement en utiliser moins. Il est essentiel de faire
assurez-vous que toutes les comparaisons portent sur des contenus de ligne à peu près égaux, sinon la différence dans le travail réel
(E/S) le traitement de chaque ligne déformera vos attentes.

De nombreux autres facteurs entrent également en jeu lors du chargement : conflit de disque dans les groupes de fichiers,
nombre une complexité des index, le nombre de fichiers contenant des données, haute disponibilité
surcharge de synchronisation, réplication, autres bases de données sur le même serveur en compétition pour
cycles de calcul et d'E/S. La liste est interminable. Plutôt que de comparer un système à un autre
un, je le compare toujours à lui-même.

par MarcoBoeringa

Les sommets par seconde sont une métrique très trompeuse. Je ne lui ferais pas trop confiance.

Les bases de données fonctionnent dans les transactions. Chaque LIGNE est traitée au total, ce qui comprend
LOBs et chaînes. Un point GeoNames à un sommet peut contenir de 8 à 10 000 données sur une seule ligne,
tandis qu'un polygone de sommets dense de 2k sans attributs pourrait facilement en utiliser moins. Il est essentiel de faire
assurez-vous que toutes les comparaisons sont pour des contenus de ligne à peu près égaux, sinon la différence dans le travail réel
(E/S) le traitement de chaque ligne déformera vos attentes.- V

Je m'en suis parfaitement rendu compte, mais les lignes / fonctionnalités en elles-mêmes sont également une mauvaise mesure, comme le montrent vos résultats :

Les entités ponctuelles à 1 sommet se chargent 15 fois plus rapidement par entité que les énormes cercles pseudo-aléatoires à 2 100 sommets.

Sans tenir compte de la rare possibilité que les utilisateurs stockent des images entières, des documents Office ou quoi que ce soit dans des LOB d'affilée d'une entité géographique, c'est une différence significative à ne pas négliger non plus.

Dire que vous avez de mauvaises vitesses de chargement de quelques entités par seconde, tout en omettant le fait que chaque polygone a des milliers de sommets, n'est donc pas non plus une question très cohérente.

Comme vous le dites, c'est un mélange de tout un tas de facteurs en jeu, y compris le nombre de caractéristiques et la taille des caractéristiques en termes de nombre de sommets.

Je pense vraiment que Keith doit encore répondre à la question de savoir pourquoi ils ont en moyenne 2100 polygones de sommets dans leurs ensembles de données. À moins que ces données ne proviennent de limites étendues de grands comtés et représentent en réalité des détails de 1:1000 ou 1:5000, et dans la pratique, elles doivent être combinées dans des superpositions géographiques et d'autres géotraitements, etc. avec des données à grande échelle de haute qualité similaires, je vois aucune raison de maintenir des fonctionnalités aussi énormes à l'échelle 1:100.000. Les données pourraient être généralisées.

Je ne pense pas qu'avoir 2100 polygones de sommets en soi soit impossible ou une mauvaise pratique, il peut y avoir de bonnes raisons de le maintenir comme ça, mais ce n'est certainement pas standard, surtout pas dans le contexte d'ensembles de données contenant des "millions" de polygones.

Je viens de réexécuter quelques statistiques sur un échantillon des ensembles de données basés sur la photogrammétrie à grande échelle dont j'ai parlé dans l'autre fil. Ce sont des données du monde réel bien entretenues :

Nombre de sommets
Total : 535334
Moyenne : 28,22
Min : 4
Max : 2106

Si vous regardez le graphique ci-dessous, la plupart des polygones ont <100 sommets ("Fréquence" verticale). L'autre image montre un exemple des données, y compris quelques couches de lignes supplémentaires, pour donner une idée du niveau de détail.

par MarcoBoeringa

Juste pour le plaisir, j'ai décidé de faire un petit test. J'ai densifié l'ensemble de données que j'avais en utilisant l'outil Densifier pour créer un ensemble de données avec un sommet tous les 0,5 mètre. J'ai supposé que cela me rapprocherait de l'ensemble de données de Keith, mais j'ai toujours du retard avec une moyenne de 540 sommets par fonctionnalité :

Résultats pour couche densifiée

Nombre de sommets
Total : 10247488
Moyenne : 540,25
Min : 4
Max : 18956

Je vais également copier l'ensemble de données d'origine, qui avait les propriétés répertoriées dans le post précédent :

Nombre de sommets
Total : 535334
Moyenne : 28,22
Min : 4
Max : 2106

Une fois le processus de densification lui-même terminé, j'ai utilisé ArcGIS 10.1 et l'outil Copier des entités pour créer une nouvelle classe d'entités à partir de celle densifiée existante, curieux de savoir combien de temps cela prendrait, et de comparer cela avec l'écriture des données au cours de la étape de densification, et la copie du jeu de données d'origine :

Copie du jeu de données d'origine non densifié :
18968 polygones densifiés en 18 secondes, donc 18968 / 18 = 1035,8 entités écrites par seconde , et 535334 / 18 = 29741 sommets écrits par seconde .

Résultats pour l'étape de densification :
18968 polygones densifiés en 9 min 2 sec, donc 18968 / 542 = 35,0 entités écrites par seconde, et 10247488 / 542 = 18906 sommets écrits par seconde.

Résultats pour l'étape Copier les entités de l'ensemble de données densifié :
18968 polygones copiés en 1 min 54 s, donc 18968 / 114 = 166,4 entités écrites par seconde , et 10247488 / 114 = 89890 sommets écrits par seconde .

La configuration de test était :
Ordinateur de bureau Acer Veriton :
- Processeur quadricœur Core i5 2320 3,00 GHz
- 6 Go de RAM (jamais utilisé complètement pendant le processus)
- Disque dur de 1 To capable de jusqu'à 180 Mo/s, connecté sur SATAII, mais n'a jamais ou rarement dépassé les E/S en lecture/écriture de plus de 10 Mo/s pendant le processus
- ArcGIS Desktop 10.1 SP1
- SQL Server Express 2012 SP1
- Ensemble de données utilisant le stockage SQL Server GEOMETRY
- Pas de versioning sur les jeux de données écrits !

« CONCLUSIONS » (à prendre avec une pincée de sel) :
Ce n'est certainement pas du matériel de serveur, mais ce n'est pas non plus un ordinateur portable à faible spécification, ni un serveur partagé enlisé par d'autres processus qui s'exécutent dessus. Je suis surpris de voir à quel point l'étape de Densification est proche des résultats de Keith :

- Keith avait 7-9 polygones "2100-sommets" écrits par seconde, avec 14700 à 18900 sommets par seconde.
- L'étape de densification est de 35,0 entités "540-sommets" écrites par seconde et de 18906 sommets par seconde
- L'étape Copier les entités est de 166,4 entités "540-sommets" écrites par seconde et 89890 sommets par seconde
- La copie de l'ensemble de données d'origine est constituée de 1035,8 entités "28 sommets" écrites par seconde et de 29741 sommets par seconde
- Vince a réalisé 113 cercles pseudo-aléatoires "2100-vertex" écrits par seconde, et +/- 240K sommets par seconde

Bien sûr, la simple étape "Copier les caractéristiques" a surpassé la densification d'un facteur 4 à 5, mais cela montre toujours qu'il y a une réelle pénalité à écrire de gros polygones avec de nombreux sommets, surtout si des étapes de calcul ou d'E/S supplémentaires sont impliquées, et cela peut en fait, le matériel de Keith fonctionne simplement à son maximum lors de l'importation de ces données.

Les résultats de Vince sur son ordinateur portable étaient encore meilleurs que les résultats de Copy Features sur mon bureau en écrivant ses cercles pseudo-aléatoires "2100-vertex" (en termes de sommets, pas en termes d'enregistrements / fonctionnalités), mais cela utilisait le se_toolkit. Il se peut que la surcharge d'ArcGIS soit le problème ici, et en plus, mon jeu de données du monde réel contient quelques champs de texte non système supplémentaires contenant des données, qui doivent également être écrits.

PS :
1) L'écriture sur SDEBINARY à l'aide de l'outil Copier les fonctionnalités a donné les résultats suivants :
18968 polygones copiés en 1 min 18 sec, donc 18968 / 78 = 243,2 entités écrites par seconde et 10247488 / 78 = +/- 131K sommets écrits par seconde .

2) J'ai également essayé d'écrire dans GEOMETRY à l'aide de Copier des entités, pour copier dans un jeu de données d'entités à l'aide d'un autre système de coordonnées et même d'un autre Datum , forçant ainsi la reprojection.
Les résultats sont :
18968 polygones copiés en 3 min 51 sec, donc 18968 / 231 = 82,1 entités écrites par seconde et 10247488 / 231 = 44361 sommets écrits par seconde .
Comme vous pouvez le voir, la re-projection ralentit la copie d'environ 1/2 de la vitesse d'origine par rapport à la copie sans re-projection (166,4 entités / 89890 sommets par seconde). Cela rend encore plus probable que les chiffres fournis par Keith ne soient en fait pas si anormaux. bien que toujours du côté bas des choses.


8 réponses 8

La journalisation des modifications est quelque chose que j'ai généralement fait en utilisant des déclencheurs sur une table de base pour enregistrer les modifications dans une table de journal. La table de journal a des colonnes supplémentaires pour enregistrer l'utilisateur de la base de données, l'action et la date/heure.

Les déclencheurs de journalisation doivent toujours être définis pour se déclencher en dernier. Sinon, un déclencheur ultérieur peut annuler la transaction d'origine, mais la table du journal aura déjà été mise à jour. C'est une situation confuse.

Fondamentalement, vous cherchez à suivre/auditer les modifications apportées à une table tout en gardant la table principale de petite taille.

Il existe plusieurs façons de résoudre ce problème. Les inconvénients et les avantages de chaque méthode sont discutés ci-dessous.

1 - Audit de la table avec déclencheurs.

Si vous cherchez à auditer la table (insertions, mises à jour, suppressions), regardez comment éviter les transactions indésirables - diaporama SQL Saturday avec code - http://craftydba.com/?page_id=880. Le déclencheur qui remplit la table d'audit peut contenir des informations de plusieurs tables, si vous le souhaitez, car les données sont enregistrées au format XML. Par conséquent, vous pouvez annuler la suppression d'une action si nécessaire en analysant le XML. Il suit qui et ce qui a fait le changement.

En option, vous pouvez avoir la table d'audit sur son propre groupe de fichiers.

2 - Datation effective des dossiers

Si vous n'allez jamais purger les données de la table d'audit, pourquoi ne pas marquer la ligne comme supprimée mais la conserver pour toujours ? De nombreux systèmes comme les personnes utilisent des datations efficaces pour montrer si un enregistrement n'est plus actif. Dans le monde de la BI, cela s'appelle une table dimensionnelle de type 2 (dimensions changeant lentement). Voir l'article de l'institut d'entrepôt de données. http://www.bidw.org/datawarehousing/scd-type-2/ Chaque enregistrement a une date de début et de fin.

Tous les enregistrements actifs ont une date de fin nulle.

3 - Modification de la capture de données (fonctionnalité d'entreprise).

Micorsoft SQL Server 2008 a introduit la fonctionnalité de capture de données modifiées. Bien que cela suive la modification des données (CDC) à l'aide d'un lecteur LOG après coup, il manque des éléments tels que qui et quoi ont effectué la modification. Détails MSDN - http://technet.microsoft.com/en-us/library/bb522489(v=sql.105).aspx

Cette solution dépend des travaux CDC en cours d'exécution. Tout problème avec l'agent SQL entraînera des retards dans l'affichage des données.

4 - Fonctionnalité de suivi des modifications (toutes les versions).

Micorsoft SQL Server 2008 a introduit la fonctionnalité de suivi des modifications. Contrairement à CDC, il est livré avec toutes les versions. Cependant, il est livré avec un tas de fonctions TSQL que vous devez appeler pour comprendre ce qui s'est passé.

Il a été conçu dans le but de synchroniser une source de données avec le serveur SQL via une application. Il y a tout un travail de cadre de synchronisation sur TechNet.

Unlike CDC, you specify how long changes last in the database before being purged. Also, inserts and deletes do not record data. Updates only record what field changed.

Since you are synchronizing the SQL server source to another target, this works fine. It is not good for auditing unless you write a periodic job to figure out changes.

You will still have to store that information somewhere.

The first three solutions will work for your auditing. I like the first solution since I use it extensively in my environment.


Way to speed up python code with numba? Includes multiple functions and two nested loops

I'm working on a program which basically preforms an N-body simulation, but with multiple potentials and soon to be time-dependant potential. Currently the program is insanely slow, whilst my supervisors code is 600 times quicker, though that is expected - it's written in C.

As you can see there are a lot of operation going on each loop. I've tried making a program which calculates the orbit for each star separately, as they are considered non-interacting with one another. The problem arises there, as I'm using a dynamic timestep, so the probability of every star being modelled until t=10000 is very low and they resulting image is inaccurate.

I searched for some kind of solution and it seems that numba is the one that perfectly fits this problem as it uses C (from what I gathered) to do all the calculations, but there is not enough info about how to use it for my specific problem.

I would've started writing in C, but again I don't have the time to start learning this as my project needs to keep moving. I've decided to post here, only because I've tried everything that I could and I really need some direction.

My program is very slow and I'm sure that when I add the time-dependant potential - it might screech to a halt. So if there's any sensible way to speed my code, I'de love to hear it and I'd be very grateful.

Edit: I should add, that I feel the other program, where I model each star separately, has the added bonus of not needing to create a huge numpy array to store coordinates. Unfortunately the problem with the timestep still stays.


You can find configuration settings for roles and databases in the catalog table pg_db_role_setting .

This query retrieves any settings for a given role or database:

If nothing is set, the next lower instance determines the default state of the search_path , which is postgresql.conf in this case or command-line options at server start. En rapport:

To unset quelconque settings of a role or database - the search_path in this particular example:

Never manipulate data in the system catalog ( pg_catalog.* ) manually. Use DDL commands as instructed in the manual for ALTER ROLE and ALTER DATABASE .
Essentially, the RESET command deletes a row from pg_db_role_setting allowing the base setting to take effect again. I wouldn't call that convoluted.

The permanent settings for both databases and roles are stored in the pg_db_role_settings system cluster-wide table.

Only settings passed to ALTER USER and ALTER DATABASE are present in this table. To get at the values that are configured aside from these commands:

The value of the setting prior to any change, including at the cluster level (through the global configuration postgresql.conf ) can be queried from the database with:

The value of the setting prior to any change within the session (through the SET command) can be queried from the database with:


8 Answers 8

Update explaination for @pradeepchhetri

If you use find with -exec , every file that find found will call rm one time. So if you found a huge of files, i.e 10000 files, you called rm 10000 times.

xargs will treat ouput of find as command argument to rm , so that, xargs will provide as many arguments as rm can handle at once, i.e rm -f file1 file2 . So it makes less fork call, make program run faster.

find … -exec rm <> executes the rm command for each file. Even though starting a new process is pretty fast, it's still a lot slower than the mere act of deleting a file.

find … -exec rm <> + would call rm in batches, which is a lot faster: you pay the cost of running rm once per batch, and each batch performs many deletion.

Even faster is to not invoke rm at all. The find command on Linux has an action -delete to delete a matching file.

However, if you're producing files at such a rate that find … -exec rm <> can't keep up, there's probably something wrong with your setup. If cache contains millions of files, you should split it into subdirectories for faster access.


Voir la vidéo: Base de données: Index en MySQL (Octobre 2021).