lunedì 14 giugno 2010

Quante cazzate (2)

Per un misterioso segno del destino sono capitato su questa pagina mentre la mia mente, per qualche motivo, stava pensando a quella fastidiosa asimmetria per cui quando dobbiamo soldi allo Stato o a un ente o azienda e non li diamo, scattano abbastanza rapidamente more, e calcoli di interessi, mentre quando è lo Stato, un ente o una azienda a doverci dei soldi, questi ci possono arrivare anche un anno dopo il termine ultimo da loro stessi fissato e sono esattamente quanto promesso (in quantità), cioè non è possibile né aggiungerci una mora né calcolarci degli interessi.


Se si obiettasse, si potrebbe ottenere in risposta che il la differenza è che loro sono "uno", noi "molti". Dunque mentre noi dobbiamo pensare solo a noi stessi (più o meno), loro devono eseguire controlli su tutti i clienti, e ovviamente ciò necessita tempo.

Ma è tale scusa sensata? Siamo nel 2010, nel XXI secolo, le aziende sono informatizzate, le transazioni economiche avvengono telematicamente... Chi è che ancora ha degli omini che fanno i conti con le calcolatrici, mandano report ai piani superiori, i quali report poi devono essere valutati da altri omini, che poi devono emettere il conto, o la notifica di non avvenuto pagamento, ...? E tali omini fanno i conti basandosi su dati prodotti e raccolti da altri omini ovviamente!

A proposito di ciò non può esistere una azienda moderna e abbastanza grande da poter accampare tale scusa, che non abbia un database per gestire i suoi affari.

Supponiamo che la nostra Azienda abbia 30 milioni di clienti (una cifra spropositata, metà della popolazione italiana... ma andiamo per eccesso!). Supponiamo che ad un certo punto si voglia sapere quanti clienti devono ancora dei soldi all'Azienda. Una semplicistica, ma funzionale, query su un ipotetico db per saperlo potrebbe essere

SELECT id, dare-avere, dare, avere, scadenza
  FROM bilanci
  WHERE (dare-avere) < 0
    AND DAY(NOW() - scadenza) > 10


dove le funzioni NOW() e DAY() non necessariamente esistono e sono lì solo per rappresentare una operazione tra date (che si legge come: differenza in giorni tra Ora e la data di scandenza è maggiore di dieci). Poi uno ci può aggiungere un JOIN con la tabella anagrafica che associa i dati anagrafici del cliente alla sua id.

Per chi non ha fantasia o non conosce nulla di SQL, questa richiesta si può leggere come: seleziona i campi id, dare meno avere (cioè la differenza tra il numero nel campo dare meno il numero nel campo avere), dare, avere e scandenza dalla tabella bilanci, dove la differenza tra dare e avere è negativa (minore di zero, cioè dobbiamo avere più di quanto è stato dato...) e sono passati più di 10 giorni dalla data di scandenza. Immaginate che questo "programmino" legga "riga per riga" di una tabella, calcoli dare meno avere e la differenza ora (il momento del controllo) e la data scandenza, e se queste quantità calcolate si uniformano ai requisiti (cioè differenza negativa tra dare e avere, e tempo dalla data di scadenza maggiore di 10 giorni), allora selezionano la riga (e precisamente i campi richiesti) e la mettono in una nuova tabella che poi è quella che viene "restituita", ed è la tabella dei risultati della query.

Il JOIN a cui ho accennato prima è un modo per usare il campo id, che identifica un cliente, per indicizzare un'altra tabella che contiene i dati anagrafici, in modo che invece di avere solo l'id (un numero) possiamo sapere nome, cognome, indirizzo ecc. del tizio che ci deve i soldi ("ci", noi siamo l'Azienda ora)

Ora prediamo il link su detto che ci dà delle performance obsolete di diversi database. Il fatto che siano obsolete ci devono far pensare che le versioni più recenti siano ovviamente più efficaci! Ora prendiamo i tempi per 5000 SELECT con indice e prendiamo il db meno performante, PostgreSQL. Approssimiamo il suo tempo in 5 secondi. Ora, il fatto che 5000 SELECT vengano fatte in 5 secondi vuol dire che una SELECT impiega circa 5/5000 secondi.

È importante la dimensione del db (cioè il fatto che ci siano 30 milioni di "righe", invece che, poniamo, 100)? No e sì... lo scopo dei db è fare questo tipo di operazioni in tempi che nel migliore dei casi sono O(1). Cioè, costanti, cioè indipendenti dal numero N di record nella tabella. Se un db implementa una roba del genere, allora sta usando buoni algoritmi di indicizzazione ecc. E i db moderni devono e possono ambire a performance O(1) posto che il db ("strutturato" da uomini) sia ben fatto. Naturalmente questo è il comportamento limite ottimale e ideale che non è sempre raggiungible, dipendentemente anche dalla complessità della query che si ha, e da alcuni "limiti" hardware (più grande il db, più dati da dover "saltare", più movimenti delle testine se i dati, come supponiamo accada, sono su un hard disk...), e come detto dal "design" del database (cioè come l'uomo l'ha strutturato e quali espedienti ha usato per miglorare le performance)

I test citati sono fatti su un db piccolo. Dobbiamo dunque peggiorarli un po' (nota: l'ho già fatto prima approssimando a 5 secondi...). Stimiamo prima le dimensioni della nostra tabella. Abbiamo 30M di utenti, per ciascuno una id da 4 byte, dare e avere (in notazione decimale variabile, essendo dati finanziari) stimiamo l'occupazione massima in 20 byte ciascuno, e una data (8 byte), dunque 52 byte per record; abbondiamo a 64 byte. Dunque il db da un punto di vista dei soli dati è grande 1.92Gbyte (solo la tabella "bilanci"), facciamo cifra tonda: 2 Gbyte. Rispetto ai 14 Mbyte del test che sto prendendo come fonte, sono 143 volte di più (sempre per eccesso).

Dunque valutiamo che una singola SELECT ci metta 143 volte di più. Poiché la nostra SELECT è leggermente più complicata di quelle di test, diciamo che ci mette 150 volte di più. Allora una singola SELECT ci mette 150*5/5000 secondi, 0.15 secondi. Abbondiamo e diciamo che ci mette 0.20 secondi. Diciamo pure che però la nostra query non è l'unica... il db viene usato "contemporaneamente" da altri per altre query per estrarre altri dati ecc. Diciamo che nell'istante in cui facciamo la nostra query, ce ne siano altre da sbrigare e questo degrada le performance di 5 volte per query, e supponiamo che ce ne siano 5000 in corso insieme alla nostra. Questo vuol dire che la nostra in particolare ci mette un tempo che è 5*5000 volte superiore all'atteso, ovvero 25000*0.2 = 5000 secondi.

Dunque tutte le nostre fantasiose stime ci portano a 5000 secondi per avere l'elenco di quelli che non hanno pagato, che ci devono dei soldi, da più di 10 giorni. In ore è 1.3889, abbondando diciamo 2 ore.

Dunque tale elenco nell'Azienda viene tirato fuori in 2 ore. Se vogliamo considerare altri misteriose combinazioni avverse, o se vogliamo complicare la query aggiungendo una JOIN con altre tabelle per i dati anagrafici, diciamo che la tabella dei morosi è tirata fuori in 8 ore. Ricordate che stiamo stimando tutto per eccesso, e partiamo dall'ipotesi "incredibile" che l'Azienda abbia 30 milioni di utenti.

Ora supponiamo che dei 30 milioni di utenti, ben il 40% risulti non in regola (cioè, sono passati 10 giorni dalla scandenza ma non hanno pagato ancora). La nostra tabella morosi conterrà 12 milioni di clienti. Vorremmo intanto notificare questi 12 milioni di clienti del fatto che non hanno pagato. Tenete presente che i costi di notifica vengono caricati sul cliente (si riesce a caricare sul cliente tutto il costo?), dunque l'Azienda non attuerà strategie per minimizzare spese inutili e procederà alla notifica (anche se il cliente paga il giorno dopo la verifica... per questo sulla notifica con bollettino verrà scritto che nel caso si sia già pagato, non bisogna fare nulla).

Ora supponiamo che per stampare e imbustare una singola notifica ci si mettano 5 secondi, e che il processo venga fatto in parallelo da 200 macchine sparse in diverse sedi/uffici dell'Azienda (la tabella viene spezzata in 200 tronconi e mandata alle varie sedi). (Ogni sede ha più di un ufficio che si occupa della faccenda, cioè l'Azienda può avere meno di 200 sedi sparse per il paese).

Dunque 5 * 12M / 200 / (3600) = 83.33 ore, arrotondiamo in 100 ore. Cento ore sono 12.5 giornate di lavoro da 8 ore, ma le nostre macchine sono macchine, e possono lavorare anche di notte (esattamente come la query, una volta impostata, può lavorare di notte: l'impiegato addetto la manda prima di staccare e il giorno dopo i dati sono belli e pronti per essere smistati per le notifiche, anche se la query ci mettesse 12 ore). Dunque servirebbero per stampare e imbustare tutto 4.17 giorni. Ma immaginiamo che ogni tanto qualche macchina si inceppi, che richieda un intervento manuale ecc. e allora accontentiamoci di un compromesso: ci vogliono 10 giorni.

Ogni sede ovviamente non aspetta di aver stampato e imbustato tutte le sue 60000 notifiche: ogni tot prende quelle prodotte giornalmente dalle macchine e le manda. Dunque in una sede al giorno vengono prodotte in media 6000 notifiche. Se ogni busta è del formato C5/6 (114×229 mm) e occupa in altezza 5 mm, stimiamo quanto spazio occupano queste 6000 notifiche su una scrivania di 1100×900 mm. "Per lungo" ci vanno 1100/115 (abbiamo messo una separazione di 1mm tra ognuna) 9, e 900/230 (3) nell'altro verso, cioè 3*9 = 27; se cambiamo orientamento: 7*4 = 28, una in più quindi scegliamo questo modo di disporle (poi si potrebbe vedere se lo spazio al bordo è sufficiente per metterci altre buste sistemate opportunamente... se qualcuna va leggermente fuori non importa, ma non ci facciamo di questi problemi e supponiamo di posizionarle solo se entrano per bene sulla scrivania).

Dunque ogni "piano" contiene 28 buste, e ogni busta è alta 3 mm (tutto sempre per eccesso); per cui 3*6000/28 = 642.86 cioè sulla nostra scrivania ci sarà questo "palazzetto" di 64 e poco più cm a fine giornata... E un ragazzotto con un carrello ne prenderà un po' alla volta (anche man mano che sono pronte e senza lasciarle accumulare) e facendo più viaggi le porterà "giù" al reparto spedizioni dove degli addetti le metteranno in sacchi (di iuta) e le metteranno da una parte... Il giorno dopo un addetto delle poste preleverà i sacchi e da questo punto in poi consideriamo le notifiche spedite.

Dunque l'ultimo gruppo di lettere per ciascuna sede viene effettivamente preso in carico il giorno dopo, per cui ai nostri 11 giorni (10 + 1 per la procedura di controllo) aggiungiamo un altro giorno. Abbiamo 12 giorni. Se in questi 12 giorni sono capitati giorni non lavorativi in mezzo in cui il processo si arresta (magari le macchine non si fermano, ma gli addetti umani sì), aggiungiamo nel peggiore dei casi altri 4 giorni (due sabati e due domeniche; non contiamo altre festività), e abbiamo 16 giorni. Supponiamo, per la posta ordinaria, tempi di consegna medi di 4 giorni.

Dunque l'ultimo "blocco" di spedizioni arriva 20 giorni dopo il controllo, mentre il primo blocco arriva dopo 7 giorni (1 elaborazione, 1 stampa, 1 reparto spedizioni, 4 consegna da parte delle poste). Poiché il controllo "becca" tutti quelli che non hanno pagato a 10 o più giorni dalla scandenza, l'ultimo blocco arriva, nel migliore dei casi, dopo 30 giorni dalla scadenza. Poiché per completare le 12M notifiche abbiamo visto servono 10 giorni, un nuovo controllo con (potenzialmente) altri 12M "evasori" non può essere fatto che al massimo ogni 10, 11 giorni (di più ma non di meno).

Nel peggiore dei casi la mia scadenza è il giorno dopo l'ultimo controllo fatto; passano dieci giorni ma sono passati solo 9 dalla scadenza per me, viene fatto un altro controllo e ancora non sono nella "lista", e passano dunque altri 10 giorni prima che mi "beccano". Dunque nel peggiore dei casi entro nella lista dopo 20 giorni e nel peggiore dei casi la notifica mi arriva perciò dopo 40 giorni.

... Non dopo 6 mesi, o 8, o 12...

E abbiamo fatto delle ipotesi di una Azienda mastodontica; a parte lo stato (che però non vanta solo 200 "sedi"), quale impresa può vantare di avere mezza Italia come cliente? Ci sono "aziende" che vantano 10 milioni di clienti... in tutta Europa... Senza contare il fatto che abbiamo supposto un approccio piuttosto fortemente centralizzato (a parte lo smistamento delle notifiche, il resto l'abbiamo pensato come un "blocco" unico che tratta tutti i dati come presenti in un unico database e con la necessità di fare controlli "dal centro"; mentre invece anche questi, come nel caso della spedizione delle notifiche, possono essere "parallelizzati").

E il numero di "sedi" distaccate può essere maggiore, e a ognuna possono essere affidati i compiti di controllo (cioè, decentralizzazione); si pensi per es. alle agenzie di una compagnia assicurativa: gestiscono un certo pacchetto di clienti, di cui naturalmente la compagnia deve essere consapevole, ma nello stesso tempo può demandare la gestione di controlli, consegna dei pagamenti e via dicendo a tali agenzie, rendendo la struttura più snella e dunque agile (e veloce).

Ora vediamo se i tempi per le imbustatrici e la stampa sono accettabili (ma diciamo subito che pensare che il 40% dei clienti non paga dopo 10 giorni dalla scandenza è anomalo). Questa imbustatrice che è la prima che ho trovato fa 900 buste all'ora, cioè 15 al minuto. I nostri 5 secondi per busta ci portano 12 buste al minuto. Tuttavia noi abbiamo i tempi di stampa, e questa macchina in particolare non carica più di 80 fogli dunque serve un addetto che ogni circa 5 minuti carica altri fogli e altre buste. Le buste ovviamente si mettono prestampate (stampate in parallelo alla notifica) e la macchina deve essere precisa e l'ordine corretto... Probabilmente il prodotto che deve esserci nelle sedi preposte è più questo o qualcosa di simile, che fa 4300 pezzi l'ora, cioè circa 71 al minuto, cioè 1.194 al secondo... cioè diciamo che ne fa una al secondo...; posiziona più "pagine" nella busta (a noi servono due fogli per busta, cioè una lettera e il bollettino).

Dagli apparecchi sul mercato si deduce che immaginare una singola azienda che debba spedire più di 80mila pezzi al mese è inconcepibile... In ogni caso l'uso di queste sofisticherie permette, considerando i tempi tecnologici per l'imbustamento, e quelli per la stampa (ho trovato laser che stampano a colori 75/55 pagine al minuto dunque riescono a stamparne una in un secondo), di poter dire che ogni busta viene preparata in 5 secondi. Se questo tempo è in effetti una certa sottostima, siamo sicuri che è abbondantemente compensata da tutte le altre sovrastime.

Altra cosa non considerata: una certa percentuale di clienti ha attivato il pagamento automatico collegato al conto, per cui non possono mai andare "in mora", a meno che il conto non sia in rosso, ma qui si aprono altri scenari. Un'altra percentuale di clienti ha scelto come metodo per essere contattati, con risparmio di carta, la posta elettronica. Un certo numero di clienti, magari quelli recidivi che ripetono spesso questi ritardi, possono essere gestiti dal call center.

Se considerate che i tempi per il controllo dei morosi è il minimo di tutto il processo, e che molte aziende sono in grado di mandare ogni mese un qualche tipo di corrispondenza ai loro clienti, e se ridimensionate più realisticamente l'azienda e il numero dei clienti... ecco che quando vi diranno con mesi e mesi di ritardo che siete morosi, farete bene a pensare male, che qualcosa non funziona nell'azienda, che i lavoratori sono inetti o, peggio, che l'azienda intenzionalmente utilizzi questa strategia "riposata" per aumentare i suoi guadagni attraverso more e calcolo di interessi.

Nessun commento:

Posta un commento

Sii educato, costruisci con cura le frasi, rifletti prima di pubblicare, evita parolacce e offese dirette, non uscire dal tema, cerca di non omettere la punteggiatura, evita errori ortografici, rileggi quel che hai scritto.