Suite

L'accélération de la requête spatiale SQL génère une erreur d'index spatial ?

L'accélération de la requête spatiale SQL génère une erreur d'index spatial ?


J'essaie de diviser les polylignes par des points qui ont un petit tampon autour d'eux. Actuellement, j'ai plus de 370 000 lignes et 320 000 nœuds et la requête s'exécute très lentement (je l'ai laissée pendant 3 jours et elle n'est toujours pas terminée). J'ai essayé de forcer un index spatial en utilisantavec (Index(SI_tempPD))mais j'obtiens l'erreur suivante :

« Le processeur de requêtes n'a pas pu produire de plan de requête pour une requête avec une indication d'index spatial. Raison : impossible de trouver la méthode spatiale binaire requise dans une condition. Essayez de supprimer les indications d'index ou de supprimer SET FORCEPLAN. »

Vous trouverez ci-dessous l'extrait de code que j'essaie d'exécuter lorsque j'obtiens l'erreur :

BEGIN INSERT INTO TempLines ( [linenum] ,[ogr_geometry] ) SELECT lines.[linenum] ,lines.[ogr_geometry].STDifference(points.[ogr_geometry].STBuffer(0.005)) AS ogr_geometry FROM dbo.TemplineData AS lines with(Index (SI_tempPD)) INNER JOIN dbo.[TemplineNodes] AS points ON lines.[ogr_geometry].STIntersection(points.[ogr_geometry]).STDistance(points.[ogr_geometry]) < 1 WHERE (lines.[linenum] <> points. [linenum]) FIN

Y a-t-il de toute façon que je peux accélérer la requête?

J'ai aussi une clé primaire en cluster. Le plan d'exécution montre qu'un filtre absorbe 36% du coût et l'insert 64%

J'utilise SQL Server 2008 (SQL server Management studio 10.50.1600.1)


Vous devez suivre les règles. Si votre requête n'atteint pas tous les points de la liste de Microsoft, l'index spatial ne sera pas utilisé par la requête.

Voir https://msdn.microsoft.com/en-us/library/ff929109.aspx

Une chose que vous faites mal : vous devez inclure dans votre clause WHERE un test qui exclut les calculs de distances qui renvoient null ou a blah.STDistance(blah) < somenumber. Ce doit être la première condition de la clause where. Le mettre dans la clause JOIN ON ne fonctionnera pas.


3 réponses 3

Dès le premier plan d'exécution publié, l'index spatial identifie les lignes qui correspondent à votre filtre de localisation en 100 ms environ, ce n'est pas votre problème. Le problème est qu'il y a près de 50 000 lignes qui correspondent à ce filtre qui doivent ensuite également être filtrées par votre filtre d'expirationDate (environ seulement 10 % correspondent à cela), ce que vous ne pouvez faire qu'en visitant les 50 000 lignes de votre table. Cela vous prend environ 3 secondes, dont seulement 0,3 seconde pour visiter les lignes dont vous avez besoin.

Malheureusement, vous ne pouvez pas inclure votre colonne de date d'expiration dans votre index spatial de localisation, sinon cela pourrait être une solution assez intéressante.

Êtes-vous en mesure de supprimer ces lignes expirées du tableau ? Le partitionnement est une solution raisonnable pour cela, mais vous auriez besoin d'une clé primaire en cluster qui devrait inclure la colonne de partitionnement, c'est une grosse question. Des processus de routine pour insérer les lignes expirées dans une autre table et les supprimer de cette table pourraient être une bonne idée.

Faire un tri top-N de ces 5 000 lignes prend environ 0,6 seconde, vous en sortiriez-vous en utilisant la colonne de clé primaire plutôt que la date de création ? Selon ce à quoi la colonne fait référence, cela peut être fortement lié - et si vous incluez simplement une colonne pour la pagination en toute sécurité, la clé primaire est sans doute le moyen le plus sûr possible. Si vous le faisiez, au lieu d'avoir à faire un tri des lignes après les avoir lues, vous n'auriez qu'à trier le résultat de la colonne de clé primaire que l'analyse de l'index spatial vous donne - cela réduirait considérablement le travail effectué si l'index spatial ne retournera que les lignes qui correspondent pour la plupart à votre filtre ExpiryDate.


Informations sur la fragmentation de l'index

L'objectif principal de la création d'un index SQL Server est d'accélérer les performances de récupération des données et d'améliorer les performances globales des requêtes. Mais lorsque les données de la table sous-jacente sont modifiées ou supprimées, cette modification doit être répliquée dans les index de table associés. Au fil du temps, et à la suite de nombreuses opérations d'insertion, de mise à jour, de suppression, l'index va devenir fragmenté, avec un grand nombre de pages non ordonnées avec de l'espace libre dans ces pages, dégradant les performances des requêtes, en raison de l'augmentation du nombre de pages à scanner afin de récupérer les données demandées. Par conséquent, l'index peut être ignoré dans la plupart des cas par l'optimiseur de requêtes SQL Server. Une autre cause du problème de fragmentation est le fractionnement de page, dans lequel la page sera divisée en deux pages lorsque les valeurs insérées ou nouvellement mises à jour ne correspondent pas à l'espace disponible dans la page, en raison d'un mauvais réglage de la Facteur de remplissage et pad_index les options de création d'index, évoquées en détail dans les articles précédents de cette série.

Le moyen le plus simple d'obtenir le pourcentage de fragmentation d'un index est de Fragmentation onglet de l'index Propriétés la fenêtre. Pour l'index nouvellement créé, le niveau de fragmentation sera de 0 %, comme indiqué dans la fenêtre Propriétés de l'index ci-dessous :

Si nous essayons de remplir les tables précédemment créées avec des enregistrements supplémentaires de 1K, à l'aide de l'outil APEXSQL Generate, comme indiqué dans l'instantané ci-dessous :

Et vérifiez à nouveau le pourcentage de fragmentation du même index, vous verrez que l'index est devenu très fragmenté, en raison de l'opération d'insertion, avec un pourcentage de fragmentation égal à 99%, comme indiqué dans la fenêtre Propriétés de l'index ci-dessous :

La vérification du pourcentage de fragmentation de tous les index dans une base de données spécifique, à l'aide de la méthode de l'interface utilisateur, nécessite un gros effort, car vous devez vérifier un index à la fois. Une autre façon de rassembler les informations de pourcentage de fragmentation sur tous les index de base de données en une seule fois consiste à interroger le sys.dm_db_index_physical_stats fonction de gestion dynamique, introduite pour la première fois dans SQL Server 2005. Le DMF sys.dm_db_index_physical_stats peut être joint au DMV sys.indexes pour renvoyer le pourcentage de fragmentation de tous les index sous la base de données spécifiée, comme dans la requête ci-dessous :

Le résultat dans notre cas sera comme indiqué ci-dessous :

Pour surmonter ce problème, nous devons effectuer l'opération de maintenance d'index appropriée, avec les valeurs FillFactor et Pad_index optimales. Dans cet article, nous nous arrêterons au moment de la collecte des informations sur la fragmentation de l'index. Dans le prochain article de cette série, nous verrons comment résoudre le problème de fragmentation d'index.


4 réponses 4

"J'ai une colonne de points définie comme SRID 4326. J'utilise MySQL 8.0.12."

J'ai un problème similaire et changer le SRID à 0 améliore considérablement les performances. Je ne sais pas si les effets secondaires sont insupportables pour toi, mais au moins tu devrais essayer ! N'oubliez pas l'autre ordre du lat et du lon si vous faites ça)

700 000 Polygones/Multipolygones complexes et un index. &ndash Josh Bernfeld 19 novembre 18 à 7:59

Suggestions à prendre en compte pour votre section my.cnf [mysqld]

veuillez consulter le profil, le profil réseau pour les coordonnées, y compris l'identifiant Skype et nous contacter.

Le SIG MySQL est toujours lent. Mais vous me dites que 3 secondes sans ORDER BY DISTANCE c'est lent dans un tableau de 10 millions de lignes ? Envisager

  1. Utiliser cette méthode pour construire les points
  2. Construire la délimitation de la boîte avec WKT pour que vous ayez quelque chose de simplifié. Je n'ai aucune idée de comment cela pourrait aider, mais c'est MySQL !
  3. Plutôt que de faire ST_Distance() < upperlimit , envisagez de faire ST_Buffer( polygon, upperlimit ) et de l'utiliser dans votre appel à ST_Contains
  4. Envisagez de passer à PostgreSQL/PostGIS et d'utiliser ST_DWithin(geom,geom,upperlimit) . PostGIS a une indexation supérieure. Il peut en fait faire tout cela sur un index car il prend en charge KNN.

Problèmes secondaires

Utilisez ascii pour les valeurs hexadécimales telles que les hachages.

Emballez les hachages hexadécimaux en binaire :

Débarrassez-vous de l'identifiant AUTO_INCREMENT et utilisez simplement hash_id.

Mieux vaudrait se débarrasser du hachage - si les données deviennent trop volumineuses pour tenir dans la RAM, elles deviendront liées aux E/S.

Algorithme plus rapide

(Bien que la question principale concerne le SIG, la question secondaire concerne l'accélération de la « recherche la plus proche ».)

Pour l'équivalent de LIMIT 50 , l'algorithme suivant touchera probablement moins de 200 lignes (et calculera les distances Great Circle uniquement pour celles-ci). (Mieux que 79 901 ?)

Analyse des VARIABLES/STATUT

Il semble que vous n'ayez pas encore beaucoup couru. Il n'y a donc pas grand chose à dire ici :

Remarques :

  • Version : 8.0.12
  • 16 Go de RAM
  • Uptime = 05:49:58 certaines valeurs GLOBAL STATUS peuvent ne pas encore être significatives.
  • Êtes-vous sûr que c'était un SHOW GLOBAL STATUS ?
  • Vous n'êtes pas sous Windows.
  • Exécution de la version 64 bits
  • Vous semblez exécuter entièrement (ou principalement) InnoDB.

Les problèmes les plus importants :

Activez le slowlog pour pouvoir identifier les requêtes lentes.

Détails et autres observations :

( (key_buffer_size - 1,2 * Key_blocks_used * 1024) / _ram ) = (1024M - 1,2 * 16 * 1024) / 16384M = 6,2% -- Pourcentage de RAM gaspillé dans key_buffer. -- Diminuer key_buffer_size.

( Key_blocks_used * 1024 / key_buffer_size ) = 16 * 1024 / 1024M = 0,00% -- Pourcentage de key_buffer utilisé. Point d'eau élevé. -- Réduisez key_buffer_size pour éviter une utilisation inutile de la mémoire.

( table_open_cache ) = 4 000 -- Nombre de descripteurs de table à mettre en cache -- Plusieurs centaines sont généralement bons.

( Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total ) = 443 594 / 786432 = 56,4% -- Le pourcentage de buffer_pool actuellement non utilisé -- innodb_buffer_pool_size est plus grand que nécessaire ?

( Innodb_os_log_write / (Uptime / 3600) / innodb_log_files_in_group / innodb_log_file_size ) = 87 040 / (20998 / 3600) / 2 / 512M = 1.4e-5 -- Ratio -- (voir minutes)

( Temps de disponibilité / 60 * innodb_log_file_size / Innodb_os_log_write ) = 20 998 / 60 * 512M / 87040 = 2.16e+6 -- Minutes entre les rotations des journaux InnoDB À partir de 5.6.8, cela peut être modifié de manière dynamique, assurez-vous également de modifier my.cnf. -- (La recommandation de 60 minutes entre les rotations est quelque peu arbitraire.) Ajustez innodb_log_file_size. (Ne peut pas changer dans AWS.)

( innodb_print_all_deadlocks ) = innodb_print_all_deadlocks = OFF -- S'il faut consigner tous les blocages. -- Si vous êtes en proie à des blocages, activez cette option. Attention : si vous avez beaucoup de blocages, cela peut écrire beaucoup sur le disque.

( join_buffer_size / _ram ) = 262 144 / 16384M = 0,00% -- 0-N par thread. Peut accélérer les JOIN (mieux pour corriger les requêtes/index) (tous les moteurs) Utilisé pour le scan d'index, le scan d'index de plage, le scan de table complet, chaque JOIN complet, etc. -- Si grand, diminuez join_buffer_size pour éviter la pression de la mémoire. Suggérer moins de 1% de RAM. S'il est petit, augmentez à 0,01% de RAM pour améliorer certaines requêtes.

( query_prealloc_size / _ram ) = 8 192 / 16384M = 0,00% -- Pour l'analyse. PCT de RAM

( query_alloc_block_size / _ram ) = 8 192 / 16384M = 0,00% -- Pour l'analyse. PCT de RAM

( net_buffer_length / max_allowed_packet ) = 16 384 / 64 M = 0,02%

( (Com_show_create_table + Com_show_fields) / Questions ) = (7 + 7) / 698 = 2,0% -- Naughty framework -- dépensant beaucoup d'efforts pour redécouvrir le schéma. -- Se plaindre au fournisseur tiers.

( (Com_insert + Com_update + Com_delete + Com_replace) / Com_commit ) = (0 + 20 + 0 + 0) / 0 = INF -- Déclarations par engagement (en supposant que tout InnoDB) -- Faible : pourrait aider à regrouper les requêtes dans les transactions Élevé : les transactions longues mettent à rude épreuve diverses choses.

( Select_scan / Com_select ) = 96 / 355 = 27,0% -- % de sélections effectuant une analyse complète de la table. (Peut être trompé par les routines stockées.) - Ajouter des index / optimiser les requêtes

( expire_logs_days ) = 0 -- Combien de temps faut-il pour purger automatiquement le binlog (après ce nombre de jours) -- Trop grand (ou zéro) = consomme de l'espace disque trop petit = besoin de répondre rapidement au crash réseau/machine. (Non pertinent si log_bin = OFF)

( slave_pending_jobs_size_max / max_allowed_packet ) = 128M / 64M = 2 -- Pour les threads esclaves parallèles -- slave_pending_jobs_size_max ne doit pas être inférieur à max_allowed_packet

( slow_query_log ) = slow_query_log = OFF -- S'il faut enregistrer les requêtes lentes. (5.1.12)

( long_query_time ) = 10 -- Seuil (secondes) pour définir une requête "lente". -- Suggérer 2

( back_log / max_connections ) = 151 / 151 = 100,0%

( Threads_created / Connections ) = 4 / 214 = 1,9% -- Rapidité de création du processus -- Augmenter thread_cache_size (non-Windows)


L'accélération de la requête spatiale SQL génère une erreur d'index spatial ? - Systèmes d'information géographique

Quelques conseils généraux pour accélérer les requêtes sur les tables MyISAM :

Pour aider MySQL à mieux optimiser les requêtes, utilisez ANALYZE TABLE ou exécutez myisamchk --analyser sur une table après qu'elle a été chargée avec des données. Cela met à jour une valeur pour chaque partie d'index qui indique le nombre moyen de lignes ayant la même valeur. (Pour les index uniques, il s'agit toujours de 1.) MySQL l'utilise pour décider quel index choisir lorsque vous joignez deux tables en fonction d'une expression non constante. Vous pouvez vérifier le résultat de l'analyse du tableau en utilisant SHOW INDEX FROM nom_table et en examinant la valeur de cardinalité. myisamchk --description --verbose affiche les informations de distribution de l'index.

Pour trier un index et des données selon un index, utilisez myisamchk --sort-index --sort-records=1 (en supposant que vous vouliez trier sur l'index 1). C'est un bon moyen d'accélérer les requêtes si vous disposez d'un index unique à partir duquel vous souhaitez lire toutes les lignes dans l'ordre en fonction de l'index. La première fois que vous triez une grande table de cette façon, cela peut prendre beaucoup de temps.

Essayez d'éviter les requêtes SELECT complexes sur les tables MyISAM qui sont mises à jour fréquemment, afin d'éviter les problèmes de verrouillage de table dus à des conflits entre les lecteurs et les écrivains.

MyISAM prend en charge les insertions simultanées : si une table n'a pas de blocs libres au milieu du fichier de données, vous pouvez INSÉRER de nouvelles lignes en même temps que d'autres threads lisent à partir de la table. S'il est important de pouvoir le faire, envisagez d'utiliser la table de manière à éviter de supprimer des lignes. Une autre possibilité consiste à exécuter OPTIMIZE TABLE pour défragmenter la table après en avoir supprimé un grand nombre de lignes. Ce comportement est modifié en définissant la variable concurrent_insert. Vous pouvez forcer l'ajout de nouvelles lignes (et donc autoriser les insertions simultanées), même dans les tables dont les lignes ont été supprimées. Voir Section 8.11.3, « Insertions simultanées ».

Pour les tables MyISAM qui changent fréquemment, essayez d'éviter toutes les colonnes de longueur variable ( VARCHAR , BLOB et TEXT ). Le tableau utilise un format de ligne dynamique s'il comprend même une seule colonne de longueur variable. Voir chapitre 16, Moteurs de stockage alternatifs.

Il n'est normalement pas utile de diviser une table en plusieurs tables simplement parce que les lignes deviennent volumineuses. Lors de l'accès à une ligne, le plus gros impact sur les performances est la recherche de disque nécessaire pour trouver le premier octet de la ligne. Après avoir trouvé les données, la plupart des disques modernes peuvent lire la ligne entière assez rapidement pour la plupart des applications. Les seuls cas où le fractionnement d'une table fait une différence appréciable est s'il s'agit d'une table MyISAM utilisant un format de ligne dynamique que vous pouvez modifier en une taille de ligne fixe, ou si vous avez très souvent besoin de parcourir la table mais n'avez pas besoin de la plupart des Colonnes. Voir chapitre 16, Moteurs de stockage alternatifs.

Utilisez ALTER TABLE . COMMANDÉ PAR expr1 , expr2 , . si vous récupérez habituellement des lignes dans expr1 , expr2 , . ordre. En utilisant cette option après des modifications importantes apportées à la table, vous pourrez peut-être obtenir des performances plus élevées.

Si vous devez souvent calculer des résultats tels que des comptages basés sur des informations provenant d'un grand nombre de lignes, il peut être préférable d'introduire une nouvelle table et de mettre à jour le compteur en temps réel. Une mise à jour du formulaire suivant est très rapide :

Ceci est très important lorsque vous utilisez des moteurs de stockage MySQL tels que MyISAM qui n'ont qu'un verrouillage au niveau de la table (plusieurs lecteurs avec un seul écrivain). Cela donne également de meilleures performances avec la plupart des systèmes de base de données, car le gestionnaire de verrouillage de ligne dans ce cas a moins à faire.

Utilisez OPTIMIZE TABLE périodiquement pour éviter la fragmentation avec les tables MyISAM au format dynamique. Voir Section 16.2.3, « Formats de stockage de table MyISAM ».

La déclaration d'une table MyISAM avec l'option de table DELAY_KEY_WRITE=1 accélère les mises à jour d'index car elles ne sont pas vidées sur le disque tant que la table n'est pas fermée. L'inconvénient est que si quelque chose tue le serveur alors qu'une telle table est ouverte, vous devez vous assurer que la table est correcte en exécutant le serveur avec la variable système myisam_recover_options définie, ou en exécutant myisamchk avant de redémarrer le serveur. (Cependant, même dans ce cas, vous ne devriez rien perdre en utilisant DELAY_KEY_WRITE , car les informations de clé peuvent toujours être générées à partir des lignes de données.)

Les chaînes sont automatiquement compressées avec les préfixes et les espaces de fin dans les index MyISAM. Voir Section 13.1.15, « Instruction CREATE INDEX ».

Vous pouvez augmenter les performances en mettant en cache les requêtes ou les réponses dans votre application, puis en exécutant de nombreuses insertions ou mises à jour ensemble. Le verrouillage de la table pendant cette opération garantit que le cache d'index n'est vidé qu'une seule fois après toutes les mises à jour.


Types d'index disponibles

En général, SQL Server prend en charge de nombreux types d'index, mais dans cet article, nous supposons que le lecteur a une compréhension générale des types d'index disponibles dans SQL Server et ne listera que les plus utilisés qui ont le plus grand impact sur l'optimisation des index SQL Server. Pour une description générale de tous les types d'index, veuillez consulter Types d'index.

  • En cluster – détermine comment les données sont écrites sur le disque, par ex. si une table n'a pas d'index clusterisé, les données peuvent être écrites dans n'importe quel ordre, ce qui rend difficile l'accès à SQL Server. Cependant, lorsqu'il est présent, un index clusterisé trie et stocke les lignes de données de la table ou de la vue généralement dans alphabétique par ordre numérique. Ainsi, si nous avons un champ d'identité avec un index clusterisé dessus, les données seront écrites sur le disque en fonction du numéro de cette identité. Il ne peut y avoir qu'un seul moyen par lequel SQL Server peut ordonner les données physiquement sur le disque et, par conséquent, nous n'autorisons qu'un seul index cluster par table. Une chose importante à savoir est qu'un index clusterisé est automatiquement créé avec une clé primaire
  • Non clusterisé – c'est le type le plus courant dans SQL Server et généralement plus d'un sur une même table. Le nombre maximal d'index non clusterisés varie en fonction de la version de SQL Server, mais le nombre va par ex. dans SQL Server 2016 jusqu'à 999 par table. Contrairement aux index clusterisés, qui organisent réellement les données, l'index non clusterisé est un peu différent. La meilleure analogie serait de le considérer comme un livre. Si nous allons à la toute fin d'un livre, il y a généralement une partie d'indexation qui contient une liste énorme de sujets et qui indique sur quelle page ils se trouvent. Un scénario typique est que le lecteur trouve un sujet/terme et qu'il pointe par ex. à un chapitre à la page 256. Si le lecteur se rend sur cette page, l'information recherchée s'y trouve. Le but est de le trouver très rapidement sans avoir besoin de parcourir tout le livre à la recherche du contenu et c'est essentiellement ce que fait l'index non clusterisé
  • Magasin de colonnes – convertit les données qui sont normalement stockées dans des colonnes et les convertit en lignes et, ce faisant, permet au moteur de base de données de rechercher plus rapidement. Ils sont la norme pour le stockage et l'interrogation de grandes tables de faits d'entreposage de données
  • Spatial – ce type d'index offre la possibilité d'effectuer certaines opérations plus efficacement sur des objets spatiaux comme la géométrie et la géographie. Ils sont quelque peu rares en dehors des systèmes SIG spécialisés
  • XML – comme son nom l'indique, ce type d'index est associé au type de données XML et ils convertissent les données XML en un format tabulaire, ce qui permet encore une fois de les rechercher plus rapidement. Il existe deux types : primaire et secondaire. Un index primaire est une exigence pour créer un index secondaire
  • Texte intégral – fournit un support efficace pour les recherches de mots sophistiquées et les requêtes en anglais dans les données de chaînes de caractères. C'est le seul type d'index qui nous permet d'exécuter un type de requête différent et de trouver des mots qui se ressemblent ou des formes différentes d'un mot, donc par exemple si une recherche de mot singulier est effectuée, l'index renverrait également un pluriel du mot spécifié

Performances de requête constantes dans le temps

Nous exécutons une charge d'application intensive (des milliers d'opérations/seconde) sur une base de données SQL Server avec pas mal de données. Certaines tables ont des milliards de lignes, plusieurs d'entre elles ont beaucoup d'insertions et de mises à jour.

Les performances de la base de données sont généralement tout à fait correctes, mais nous rencontrons périodiquement des problèmes de performances des requêtes, des requêtes plutôt simples qui fonctionnaient très bien auparavant peuvent prendre 10 à 100 fois plus de temps tout d'un coup.

Cela semble être lié aux statistiques de table/index et à l'optimiseur de requêtes - la plupart du temps, une mise à jour des statistiques résoudra le problème, puis d'autres fois, une mise à jour des statistiques aggravera la situation (la réexécution de la mise à jour des statistiques résoudra alors généralement le problème finalement).

Ce qui semble se produire, c'est que l'optimiseur décide d'utiliser des index objectivement faux pour certaines requêtes tout d'un coup, après avoir utilisé le bon pendant des jours et des semaines.

Ma question est : pourquoi cela se produit-il et que pouvons-nous faire à ce sujet ?

Cette base de données fonctionne depuis des années avec essentiellement la même charge, à peu près les mêmes requêtes et le même nombre de mises à jour. Pour 99,995% des requêtes, il ne devrait y avoir aucune raison de décider de différentes stratégies d'indexation au fil du temps, quelle que soit l'entrée (et - en effet - cela détruira manifestement complètement les performances des requêtes).

Comme indiqué ci-dessus, la mise à jour automatique des statistiques selon un calendrier générera souvent d'horribles problèmes - si l'échantillon de statistiques est faussé (ce qui semble se produire au moins 5 % du temps), nous nous retrouvons dans un monde douloureux.

Existe-t-il un moyen de dire à SQL Server (sur certaines tables) que l'histogramme et la densité des statistiques ne changeront pas au fil du temps, veuillez donc continuer à utiliser le même plan de requête pour les requêtes impliquant cette table ? Si non, comment pouvons-nous garantir un résultat prévisible de la mise à jour des statistiques au fil du temps (en évitant le problème de statistiques asymétriques décrit ci-dessus) ?

Aucune procédure stockée. Nous avons le contrôle sur le SQL, il peut donc potentiellement être modifié, mais il s'agit de BEAUCOUP de code, il serait donc regrettable que nous devions modifier chaque requête (par exemple, en ajoutant une clause supplémentaire).

Une question de suivi : le reniflage de paramètres ne semble être pertinent que pour les procédures stockées, est-ce correct ?


Analyseur de journal de requête lente

Résume et optimise les fichiers journaux des requêtes lentes plusieurs requêtes à la fois. Cela inclut des informations sur les requêtes qui prennent plus de temps à traiter.

Optimisez plusieurs requêtes à la fois

optimisez les requêtes directement à partir du fichier journal lent de MySQL, tout en récupérant les meilleurs index pour plusieurs requêtes à la fois.

Tableaux de bord riches en GUI

L'interface utilisateur riche de SmartMySQL permet à SmartMySQL de faire tout le travail pour vous afin que vous puissiez améliorer vos performances.

Les requêtes sont regroupées par condensé et signalées par ordre décroissant de temps de requête avec notation des requêtes

Pas besoin de compétences spéciales

Il est utile pour ceux qui exécutent des serveurs MySQL sans ingénieurs de performance MySQL et DBA.


3 réponses 3

Je ne sais pas s'il s'agit d'un bogue, mais le seul moyen d'obtenir des données de géométrie pour les répliquer avec succès est d'utiliser les paramètres suivants sur l'éditeur (Propriétés de l'article, définir les propriétés pour toutes les tables) :

Étrangement, "Convertir les types de données spatiales en MAX" ne résout pas le problème. Il est également nécessaire de sélectionner "Copier les index spatiaux - Vrai" pour la prise en charge des index spatiaux. A part ça, les valeurs par défaut devraient être correctes.

Pour produire l'erreur ci-dessus, suivez les étapes ci-dessous :

--ÉTAPE 1 : Créer une base de données sur SQL Server 2008 r2 Enterprise ou Developer Edition créer un test de réplication de base de données aller

SI OBJECT_ID ( 'dbo.SpatialTable', 'U' ) N'EST PAS NULL DROP TABLE dbo.SpatialTable GO

--ÉTAPE 2: créez une table stockant le type de données de géométrie CREATE TABLE SpatialTable ( id int IDENTITY (1,1), GeomCol1 geometry, GeomCol2 AS GeomCol1.STAsText() ) GO

--ÉTAPE 3: insérer des exemples d'enregistrements INSERT INTO SpatialTable (GeomCol1) VALUES (geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0))

--ÉTAPE 4 : --configurer le distributeur sur cette édition d'entreprise --Créer une publication sur la base de données ci-dessus

--ÉTAPE 5 : Créer un abonné sur SQL Server 2008 r2 édition express (à l'aide d'un abonnement push)

--ÉTAPE 6 : une fois l'instantané appliqué, les deux bases de données sont synchronisées

--ÉTAPE 7: Insérez une ligne dans le tableau ci-dessus sur l'éditeur INSERT INTO SpatialTable (GeomCol1) VALUES (geometry::STGeomFromText('POLYGON ((0 0, 150 0, 150 150, 0 150, 0 0))', 0) ) ALLER

--ÉTAPE 6 : Lancez le moniteur de réplication et observez l'erreur :

L'Agent de fusion a échoué car le schéma de l'article sur l'éditeur ne correspond pas au schéma de l'article sur l'abonné. Cela peut se produire lorsqu'il y a des modifications DDL en attente d'être appliquées à l'Abonné. Redémarrez l'Agent de fusion pour appliquer les modifications DDL et synchroniser l'abonnement. (Source : MSSQL_REPL, Numéro d'erreur : MSSQL_REPL-2147199398) >


Voir la vidéo: LINUX passer de USER a ROOT Élévation de privilèges