técnicas de optimización masiva de datos de Django Admón.

Tomado del producto es ligeramente Biblioteca  http://www.pinlue.com/article/2020/04/0211/3710102817445.html

prefacio

Recientemente ayudé a un amigo para hacer frente a algún tipo de datos de saldos, usando la Web como el marco de Django.

Módulo de administración de Django es una de mis favoritas Django mejor que el frasco razón importante.

Los proyectos pequeños, si es para su propio uso, no es tan especial acerca de la interfaz de administración, el uso de Django El administrador puede escribir menos código bajo un poco de inferioridad numérica.

Me gustaría sincronizar algunos datos para las acciones durante cinco minutos y escribir un simple páginas de administración de Django, resolver dos problemas menores, se encontró no tuvo tiempo para actualizar una columna, un agua rápidamente, entonces la gente desea dar un poco de optimización referencia en la idea

0x01 cosas comenzaron a cambiar de

Cuando la cantidad de datos aumentó a cincuenta millones de a un solo centenar de millones, abrí la página correspondiente de administración de Django desea ver algunos datos. Abrir la página tarda una media de un minuto, esta velocidad de la página puede ser bastante lento.

Necesidad de explicar a mi ModelAdmin Así está escrito

@ Admin.register (Stock5Min) Stock5MinAdmin clase (ReadOnlyAdminMixin, admin.ModelAdmin): list_display = ( "stock_name", "código", "fecha y hora", "fecha",,, "baja" "alta" "abierto", "cerrar ",) stock_name def (auto, ejemplo): instance.stock.name retorno

Así, iniciar la colocación de un problema

Abrir las Herramientas de Desarrollo devuelve una respuesta por parte del juez en el contenido, no debe ser demasiado grande o html JS infinita fuga de bucle / memoria. Excluidos son la punta del problema.

Instalar django-debug-herramientas de posicionamiento de monitoreo.

SQL puede ser visto desde el Panel debe básicamente atrapado en el SQL anterior para entrar en la página para ver detalles

Hay dos problemas:

Pregunta 1: recuento de datos masivos

Rojo y azul dos instrucción SQL es particularmente evidente en los dos huesos duros, y se encontró que después de la implementación, la ejecución es el recuento

contar cada vez que necesite un escaneo completo de tabla, por supuesto, un poco lento, lento es un problema, aún más embarazosa se realiza dos veces

2 problemas: n + 1 temas

Th consulta número 105, no se duplica similares, este es el rendimiento de la ORM norma n + 1.

0x02 resolver el problema

Bueno, para empezar

contar de datos masivos

Ampliar el código relevante de la información de la pila en django-debug-herramientas

Sobre la base de código Pathfinder y encontraron que hay dos áreas de necesidad de optimizar el recuento

# Odin-py3.7 / lib / python3.7 / site-packages / django / contrib / admin / views / main.pyclass lista de cambios: get_results def (self, petición): paginador = self.model_admin.get_paginator (solicitud, auto. queryset, self.list_per_page) RESULT_COUNT = paginator.count # 这里 是 COUNT1 优化 点 # obtener el número total de objetos, sin filtros de administración aplicada. Si self.model_admin.show_full_result_count: full_result_count = self.root_queryset.count () # 这里 是 Cont2 优化 点 otra cosa: full_result_count = Ninguno

Cont2 parecen facilitar la comparación, de la siguiente manera ModelAdmin añadir, omitir Cont2

show_full_result_count = False

COUNT1 re-optimización, siempre y cuando el número de cambios para hacer paginador ideal es suficiente, ya que el número es cercano a 100 millones de dólares, por lo que en ModelAdmin especifica en la siguiente paginador bien

clase LargeTablePaginator (Paginator): _get_count def (auto): 100000000 retorno count = propiedad (_get_count)

Desde entonces, se habría requerido años 40 + páginas, son sólo 6s

Esta vez que saltar fuera inteligente

Esta optimización es retardado mental, ¿cómo puede un número tan especificado de recuento. Este no es un problema de escapar de ella ...

Pero evitar una vergüenza, pero muy útil.

broma

Ingenioso escritor, de hecho, ya se sabe lo que piensa,

Me abstendré, vaya a resolver los problemas dejados por 6s volver más tarde.

Resolver el problema de N + 1

Y llena con un similares consultas repetidas, N + 1 Bacheng este problema, es decir,

instance.stock.name cuando será el momento de tomar la base de datos de valores, que dio lugar a una serie de base de datos de hit, consulta la base de datos cada golpe, aunque el tiempo se acaba, pero la conversación en sí es una pérdida frecuente

N + 1 problema no es más que tipo de soluciones

Django construido selectrelated lograr leftjoin

Django construida stock prefetchrelated tomada de antemano con el fin de alcanzar el objetivo de reducir el número de bases de datos hit

Laminado de documentos oficiales, que se encuentra admin.ModelAdmin en apoyo de la primera opción,

list_select_related = [ "Stock"]

Desde entonces, habría requerido la página 6 s, la página ya está abierto un poco menos de 1s, base de datos de vez en menos de 200 ms

0x03 cuatro tipos de programa de conteo rápido

Bueno, entonces pendiente ante dicho empezamos a resolver el problema

Y pensar en la cuenta número es realmente lo que es particularmente importante?

De hecho, el número exacto no es especialmente necesario, en otras palabras, si el número es ahora cien millones, tres minutos después de que yo

Esta tabla será una cantidad de $ 201 300, cuando todavía era de cien millones de problema de madera.

Obviamente, en este escenario, no hay problema en absoluto.

Así el esquema 1, es decir, antes de que el programa es realmente buena.

Escenario 1: es la más sencilla y directa para estimar una cantidad de carne humana

def _get_count (auto): retorno 100000000

Si usted dice, quiero un poco de punto de datos reales, lo que puede

Esquema 2: una memoria intermedia de valor de recuento de temporización

Opción 2 sería más apropiado a continuación, algunas de las

def _get_count (auto): clave = "stock5min" count = cache.get (llave) si no cuentan: recuento = do_count () cache.set (clave, recuento, 30 * 60) # 每 三 小时 刷 一次 recuento de retorno

Si usted dice, no quiero utilizar las Redis caché como, pero tengo que estar relativamente cerca de la cantidad real de código

O, como MySQL o postges tabla no es ninguna metadatos me puede dar para leer, obtener un general

Número de escenarios cosa?

Sí, la opción 3

Esquema 3: Meta leer tabla de valores

Con PG, por ejemplo, podemos proporcionar programa de tres prácticas

pgclass

def _get_count (auto): si getattr (auto, "_count", ninguno) no es Ninguno: el retorno consulta self._count = self.object_list.query si no query.where: # 如果 走 全 表 recuento tratar: Cursor = conexión. cursor () cursor.execute ( "reltuples Selecciona de pg_class DONDE relname =% s", [query.model._meta.db_table]) self._count = int (cursor.fetchone () [0]), excepto: self._count = super () ._ get_Count () else: self._count = super () ._ get_Count () self._count retorno

Lo otro programa que? Por supuesto, la opción IV.

Programa 4: contar tiempo de espera especificado

Si la cuenta excede el tiempo de ejecución de 200 ms, por defecto a un número.

def _get_count (auto): con transaction.atomic (), connection.cursor () como cursor: cursor.execute ( "SET statement_timeout LOCAL DE 200;") Proveedores:. súper retorno () contará con excepción OperationalError: retorno 100000000

Página estable a 1s tiempo de apertura alrededor, la optimización se ha completado, la terminación

 

Publicado 60 artículos originales · ganado elogios 58 · Vistas de 140.000 +

Supongo que te gusta

Origin blog.csdn.net/yihuliunian/article/details/105340917
Recomendado
Clasificación