Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
cap:tsql [2017/05/25 23:44] cesar.vega |
cap:tsql [2018/02/20 09:13] (actual) |
||
---|---|---|---|
Línea 154: | Línea 154: | ||
Recuperar la parte superior ( 1 ) **ORDEN DE FILA POR TECLA** | Recuperar la parte superior ( 1 ) **ORDEN DE FILA POR TECLA** | ||
+ | |||
Mientras que **CURRENT KEY NO ES NULO** | Mientras que **CURRENT KEY NO ES NULO** | ||
+ | |||
**EMPEZAR** | **EMPEZAR** | ||
+ | |||
Proceso **FILA CON LLAVE CORRIENTE** | Proceso **FILA CON LLAVE CORRIENTE** | ||
+ | |||
Recuperar la parte superior ( 1 ) **FILA** | Recuperar la parte superior ( 1 ) **FILA** | ||
+ | |||
**DÓNDE CLAVE** > **ORDEN CLAVE ACTUAL POR TECLA** | **DÓNDE CLAVE** > **ORDEN CLAVE ACTUAL POR TECLA** | ||
+ | |||
**FIN** | **FIN** | ||
Línea 234: | Línea 240: | ||
La entrada a la consulta es un conjunto, y la salida es un conjunto. No está obligado a agregar orden de presentación a la consulta. Si decide agregar orden de presentación, no tiene que ser el mismo que el pedido en la función de ventana. Esa es una gran característica de diseño. Si TOP y OFFSET / FETCH hubieran sido diseñados de manera similar, habría mucha menos confusión sobre su uso. | La entrada a la consulta es un conjunto, y la salida es un conjunto. No está obligado a agregar orden de presentación a la consulta. Si decide agregar orden de presentación, no tiene que ser el mismo que el pedido en la función de ventana. Esa es una gran característica de diseño. Si TOP y OFFSET / FETCH hubieran sido diseñados de manera similar, habría mucha menos confusión sobre su uso. | ||
+ | |||
+ | ==== Piensa en Cloud ==== | ||
+ | |||
+ | Microsoft está invirtiendo mucho en la tecnología de la nube, haciéndola más rica y más potente. Para algunas aplicaciones, es inevitable que la base de datos residirá en la nube en un momento u otro. Se dedica mucho esfuerzo a tener una base de código para las versiones de caja (en premisas) y de nube (SQL Azure), pero hay algunas diferencias que debe tener en cuenta. La comprensión de las diferencias puede afectar la forma de escribir el código si desea una migración fluida (si y cuando migra). | ||
+ | |||
+ | Libros en pantalla de SQL Server detalla las características de idioma que están o no están disponibles en SQL Azure. Aquí sólo quiero mencionar un par de ejemplos para darle una idea de lo que significa codificar con T-SQL contra una caja mientras se piensa en la nube. | ||
+ | |||
+ | En SQL Azure no hay soporte para montones, sino sólo árboles B. Esto tiene que ver con el sistema de replicación interno utilizado por SQL Azure para mantener varias copias de la base de datos con fines de recuperación de desastres. Hay implicaciones en el hecho de que los montones no son apoyados. Por ejemplo, como resultado, no se admite el comando SELECT INTO. Recuerde que SELECT INTO no copia índices del origen, incluido el índice agrupado. En otras palabras, SELECT INTO siempre crea un montón y por lo tanto no está soportado en SQL Azure. Cuando escribe un nuevo código, en lugar de utilizar SELECT INTO, si utiliza CREATE TABLE seguido de INSERT SELECT, su código estará preparado para la nube en este aspecto. | ||
+ | |||
+ | Otro ejemplo es el hecho de que en SQL Azure no se puede cambiar entre bases de datos dentro de la misma conexión. La instrucción USE es compatible, pero sólo funciona si ya está conectado a la base de datos de destino. Intente cambiar a una base de datos diferente y obtendrá un error. Con esto en mente, evite el código que alterna entre diferentes bases de datos si es posible. | ||
+ | |||
+ | El acceso directo a tempdb no está permitido en SQL Azure. Se le permite crear tablas temporales y declarar variables de tabla, pero no se le permite conectarse directamente a tempdb y crear objetos de usuario. Por lo tanto, debe evitar el acceso directo a tempdb. | ||
+ | |||
+ | Otro ejemplo de diferencia entre las versiones en caja y en nube de SQL Server es que en una versión de caja se lee el nivel de aislamiento predeterminado, mientras que en la nube se lee la instantánea confirmada. Comprender la diferencia entre los aislamientos es muy importante. Creo que la mayoría de los ambientes que usan read committed hoy en día en una versión de caja pueden beneficiarse enormemente de la transición a la lectura de instantáneas comprometidas. Por lo tanto, se recomienda que aprenda y entienda el valor de leer la instantánea y el plan comprometidos para la transición en algún momento. Entonces, por supuesto, la migración a la nube será más fácil. | ||
+ | |||
+ | Estos ejemplos ilustran lo que entiendo por "pensar en la nube" al codificar con T-SQL contra una caja. Para obtener más información sobre T-SQL en SQL Azure, consulte " Referencia de Transact-SQL (Base de datos de SQL Azure) ". | ||
+ | |||
+ | ==== Mejores prácticas de fecha y hora ==== | ||
+ | |||
+ | Existen muchas prácticas recomendadas relacionadas con el trabajo con datos de fecha y hora. Sin embargo, quiero mencionar dos malos hábitos particularmente comunes que recomiendo evitar. | ||
+ | |||
+ | **Utilizar literales neutros en el lenguaje.** Cuando se expresa literales de fecha, una práctica común es usar un formulario que dependa del idioma, ya que para eso se utiliza el desarrollador (por ejemplo, el formulario '01 / 02/11 '). Sin embargo, dependiendo del idioma del inicio de sesión conectado a SQL Server y ejecutando el código, este formulario puede interpretarse de varias maneras diferentes. Para un inicio de sesión con inglés de EE.UU., este formulario significaría mes / día / año; Para uno con inglés británico, significaría día / mes / año; Y para uno con japonés, significaría año / mes / día. Como desarrollador, no desea utilizar un formulario que se interpretará de forma diferente dependiendo del idioma del inicio de sesión que ejecute su código. La mejor práctica es usar un formulario que sea neutral en el lenguaje. Por ejemplo, cuando se utiliza '20110102', SQL Server siempre interpretará la fecha como YYYYMMDD porque este formulario es neutral del lenguaje. Es necesario tener especial cuidado con el formulario '2011-01-02', ya que para los tipos de fecha y hora más antiguos (DATETIME y SMALLDATETIME), depende del idioma (lea como YYYY-MM-DD para algunos y AAAA-DD- MM para otros), mientras que para los tipos más nuevos (DATE, DATETIME2 y DATETIMEOFFSET), siempre se interpreta como AAAA-MM-DD. Piense en usar este formulario en su código, y luego en algún momento alterando el tipo de su atributo. Su código podría cambiar repentinamente su significado. Por lo tanto, prefiero pegarme a la forma YYYYMMDD para todos los tipos - viejo y nuevo, donde siempre se interpreta de la misma manera. | ||
+ | |||
+ | **Tenga cuidado con los errores de redondeo.** Suponga que está utilizando el tipo de datos DATETIME para su columna y sus datos tienen valores de fecha y hora que no son necesariamente medianoche. Desea filtrar un período de datos de fecha y hora como enero de 2012. Algunas personas utilizan el siguiente formulario de filtro: | ||
+ | |||
+ | <code sql> | ||
+ | WHERE col BETWEEN '20120101' AND '20120131 23:59:59.999' | ||
+ | </code> | ||
+ | El problema es que 999 como la unidad de milisegundos no es una multiplicación de la unidad de precisión para DATETIME, que es de tres y un tercer milisegundos. Por lo tanto, el valor se redondea a la siguiente medianoche, y su rango podría terminar incluyendo filas que no se supone que incluya. Algunas personas "solucionan" este problema utilizando 997 en la unidad de milisegundos, pero ¿qué pasa si en algún momento en el futuro se altera el tipo a uno con precisión más fina? Por lo tanto, la mejor práctica con rangos de fecha y hora es evitar BETWEEN y utilizar siempre el formulario: | ||
+ | |||
+ | <code sql> | ||
+ | WHERE col >= '20120101' AND col < '20120201' | ||
+ | </code> | ||
+ | |||
+ | Este formulario funciona con todos los tipos y todas las precisiones, independientemente de si la parte de tiempo es aplicable. | ||
+ | |||
+ | ==== Escribir código estándar ==== | ||
+ | |||
+ | T-SQL tiene varios elementos de lenguaje patentados. Algunos tienen contrapartes que son compatibles con SQL estándar (ISO y ANSI). Encuentro que es importante hacer un esfuerzo para escribir el código estándar a menos que haya una razón substancial de hacer de otra manera, tal como funcionalidad adicional o mejor funcionamiento. Siguiendo el estándar le permite escribir código que sea más portátil entre plataformas. Pero no es sólo su código que se vuelve más portátil; Su conocimiento lo hace también. | ||
+ | |||
+ | En " Prácticas recomendadas de T-SQL, Parte 1 ", recomendé terminar las sentencias T-SQL con un punto y coma. También debe tratar de atenerse a las funciones estándar y los operadores. Por ejemplo, la función CAST es estándar, mientras que la función CONVERT no lo es. Si no está confiando en el argumento de estilo opcional que CONVERT admite pero CAST no lo hace, utilice CAST. COALESCE es estándar, mientras que ISNULL no lo es. COALESCE es más flexible que ISNULL, así que usarlo es una situación de ganar-ganar. El operador <> es estándar, mientras que el operador = no lo es - así que la recomendación obvia es usar <>. | ||
+ | |||
+ | Estos ejemplos simplemente le dan un sentido de las prácticas de codificación estándar. Es importante aprender lo que es estándar y lo que no es y seguir el estándar cuando sea posible. | ||
+ | |||
+ | ==== Tenga cuidado con las reglas del pulgar ==== | ||
+ | |||
+ | A la gente le gustan las reglas básicas, pero no siempre existen. He visto muchas de esas reglas que probablemente fueron creadas basadas en observaciones muy limitadas y luego hicieron una regla. ¿Ha oído reglas básicas como "Usar combinaciones porque son más eficientes que las subconsultas" o "Si tiene más de n tablas en una sola consulta, rompúela con varias consultas"? La realidad es que a veces las uniones son más eficientes que las subconsultas, a veces viceversa, ya veces se optimizan lo mismo. A veces, una sola consulta con 20 uniones funcionará muy bien y una consulta con 4 combinaciones funcionará mejor si se divide en pasos que rellenan las tablas temporales que se unen a continuación. La optimización del código de T-SQL es un proceso tan dinámico y sofisticado que las reglas del pulgar como éstas no ayudarán pero en lugar de otro le engañarán. Si usted insiste en adoptar una regla general, hágalo "Mantenga una mente abierta, y tenga cuidado con las reglas del pulgar." Esto siempre debe ser cierto ... tal vez ... | ||
+ | |||
+ | ==== Usar argumentos de búsqueda ==== | ||
+ | |||
+ | Al optimizar una consulta y considerar si y cómo usar índices, uno de los elementos clave que el optimizador evalúa son los predicados en los filtros de consulta. Sin embargo, hay que tener en cuenta que para confiar en ordenar el índice (por ejemplo, realizar una búsqueda de índice o un escaneo ordenado), el predicado debe ser de una forma particular. Específicamente, con excepción de muy pocas excepciones, debe intentar evitar la manipulación de las columnas de clave de índice. En la mayoría de los casos, después de aplicar la manipulación, el optimizador no puede confiar en que el resultado de la manipulación conserva el orden del índice. A veces no hay mucho que puedas hacer para evitar la manipulación, pero a veces puedes hacerlo. Cuando el optimizador puede confiar en el ordenamiento de índice para un predicado dado, se dice que el predicado es un argumento de búsqueda, o SARG para abreviar. Aquí están algunos ejemplos: | ||
+ | |||
+ | * El predicado COALESCE (T1.col1, -1) = COALESCE (T2.col1, -1) no es un SARG, mientras que el predicado T1.col1 = T2.col1 OR (T1.col1 IS NULL y T2.col1 IS NULL ) es. | ||
+ | * El predicado col1 - 1 <= @ n no es un SARG, mientras que el predicado col1 <= @ n + 1 es. | ||
+ | * El predicado LEFT (col1, 3) no es un SARG, mientras que el predicado col1 LIKE 'abc%' es. | ||
+ | |||
+ | Como puede ver, a veces las revisiones simples de sus predicados pueden retener el significado y permitir un uso eficiente de la indexación. | ||
===== Origenes de Información ===== | ===== Origenes de Información ===== | ||
Línea 240: | Línea 303: | ||
[[wp>Lógica_de_primer_orden|Lógica de Predicados]] | [[wp>Lógica_de_primer_orden|Lógica de Predicados]] | ||
+ | |||
+ | [[http://sqlmag.com/article/tsql/thinking-in-sets-129772|T-SQL Foundations: Thinking in Sets]] | ||
+ | |||
+ | [[http://sqlmag.com/t-sql/t-sql-best-practices-part-1|T-SQL Best Practices, Part 1]] | ||
+ | |||
+ | [[http://sqlmag.com/t-sql/t-sql-best-practices-part-2|T-SQL Best Practices, Part 2]] | ||
+ | |||
+ | [[http://searchsqlserver.techtarget.com/tip/Nine-T-SQL-best-practices|Nine T-SQL best practices]] |