mysql finding field population of multiple columns the efficient way?
(COUNT(NULLIF( Email, '' )) --> COUNT(Email)

COUNT(col) is the same as COUNT(*) except for ignoring rows when col is NULL.

So..

SELECT
    COUNT(Email)              AS '#Email',
    COUNT(Email)*100/COUNT(*) AS '%Email',
    COUNT(fname)              AS '#fname',
    COUNT(fname)*100/COUNT(*) AS '%fname',
    ...


would give you 300 columns.

For 150 rows:

SELECT
    'Email'                   AS 'Column',
    COUNT(Email)              AS '# Populated',
    COUNT(Email)*100/COUNT(*) AS '% Populated'
    FROM tbl
UNION ALL
SELECT
    'fname',
    COUNT(fname),
    COUNT(fname)*100/COUNT(*)
    FROM tbl
UNION ALL
...


Notes:


The former uses one pass over the data; the latter needs 150 passes.
If you are using the commandline mysql, use \G to make the display more readable.
UNION defaults to UNION DISTINCT, which makes an extra pass over the result to de-dup.  UNION ALL skips that; it is unnecessary in your case.
The AS is needed on only the first SELECT of a UNION.  (If present on others, it is ignored.)


If you want to turn NULL into 0, be more efficient by doing the test outside the count:

    IFNULL(COUNT(Email), 0)              AS '# Populated',
    IFNULL(COUNT(Email), 0)*100/COUNT(*) AS '% Populated'


Other counting techniques:

SUM(Email != '')        -- excludes both NULLs and empty strings
SUM(Email IS NOT NULL)  -- excludes NULLs  (Same as COUNT(Email))
SUM(Email IS NULL)      -- includes only NULLs


A boolean expression evaluates to 0 or 1 (or NULL); SUM then adds up the ones.