Tengo una tabla que almacena algunos datos básicos acerca de las sesiones de usuario en los sitios web de terceros. Esta es su estructura:MySQL para una mesa con varios índices que el índice de algunas de las mismas columnas
id, site_id, unixtime, unixtime_last, ip_address, uid
Hay cuatro índices: id
, site_id/unixtime
, site_id/ip_address
y site_id/uid
Hay muchos tipos diferentes de maneras que consultar esta tabla, y todos ellos son específicos de la Identificación del sitio. El índice con unixtime se usa para mostrar la lista de visitantes para una fecha o rango de tiempo determinado. Los otros dos se utilizan para encontrar todas las visitas desde una dirección IP o un "uid" (un valor de cookie único creado para cada visitante), así como para determinar si este es un visitante nuevo o un visitante que regresa.
Obviamente, almacenar site_id dentro de 3 índices no es eficiente tanto para la velocidad de escritura como para el almacenamiento, pero no veo forma de evitarlo, ya que necesito poder consultar rápidamente estos datos para un site_id específico.
¿Alguna idea sobre cómo hacer esto más eficiente?
yo no entiendo muy bien los árboles B, además de algunas cosas muy básicas, pero es más eficiente que la columna más a la izquierda de un índice sea el que tiene la menor varianza - ¿correcto? Porque consideré que site_id es la segunda columna del índice para ip_address y uid, pero creo que eso haría que el índice sea menos eficiente ya que el IP y el UID van a variar más de lo que lo haría el ID del sitio, porque solo tenemos alrededor de 8000 sitios únicos por servidor de base de datos, pero millones de visitantes únicos en todos los ~ 8000 sitios a diario.
También he considerado eliminar site_id de los índices IP y UID por completo, ya que las posibilidades de que el mismo visitante vaya a varios sitios que comparten el mismo servidor de base de datos son bastante pequeñas, pero en los casos donde esto sucede, me temo podría ser bastante lento determinar si este es un nuevo visitante a este site_id o no. La consulta sería algo así como:
select id from sessions where uid = 'value' and site_id = 123 limit 1
... así que si este visitante había visitado este sitio antes, sería sólo es necesario encontrar una fila con este site_id antes de detenerse. Esto no sería necesariamente súper rápido, sino aceptablemente rápido. Pero digamos que tenemos un sitio que recibe 500,000 visitantes por día, y un visitante en particular ama este sitio y va allí 10 veces al día. Ahora llegan a otro sitio en el mismo servidor de base de datos por primera vez. La consulta anterior podría llevar bastante tiempo para buscar entre todos los miles de filas potencialmente para este UID, diseminadas por todo el disco, ya que no encontraría una para este ID de sitio.
Cualquier penetración en hacer esto lo más eficiente posible sería apreciado :)
actualización - esto es una tabla MyISAM con MySQL 5.0. Mis preocupaciones son tanto con el rendimiento como con el espacio de almacenamiento. Esta tabla es tanto lectura como escritura pesada. Si tuviera que elegir entre rendimiento y almacenamiento, mi principal preocupación es el rendimiento, pero ambos son importantes.
Utilizamos MemCached fuertemente en todas las áreas de nuestro servicio, pero eso no es una excusa para no preocuparse por el diseño de la base de datos. Quiero que la base de datos sea lo más eficiente posible.
motor de almacenamiento? ¿versión de mysql? ¿Y cómo quiere que esto sea más eficiente, en cuanto al uso del disco o al rendimiento? ¿Y tienes problemas reales para resolver o es solo una pregunta retórica? – ggiroux
mysql 5.0, motor myisam. Me preocupan tanto el espacio de almacenamiento como el rendimiento, ya que esta es una mesa pesada de lectura y escritura. Sí, problema real. :) – Sean
¿Has leído Alto rendimiento MySQL? –